Bladeren bron

楼层平面图切换ok

xzw 3 jaren geleden
bovenliggende
commit
dfde12b075

+ 21 - 16
libs/three.js/build/three.module.js

@@ -208,7 +208,7 @@ function EventDispatcher() {}
 
 Object.assign( EventDispatcher.prototype, {
 
-	addEventListener: function ( type, listener ) {
+	addEventListener: function ( type, listener, importance=0 ) {//add importance
 
 		if ( this._listeners === undefined ) this._listeners = {};
 
@@ -220,10 +220,10 @@ Object.assign( EventDispatcher.prototype, {
 
 		}
 
-		if ( listeners[ type ].indexOf( listener ) === - 1 ) {
-
-			listeners[ type ].push( listener );
-
+		if ( listeners[ type ].indexOf( listener ) === - 1 ) { 
+			//listeners[ type ].push( listener );
+            listeners[type].push({ listener,  importance});
+            listeners[type] = listeners[type].sort((e,a)=> a.importance - e.importance)//add
 		}
 
 	},
@@ -247,19 +247,22 @@ Object.assign( EventDispatcher.prototype, {
 
 		if ( listenerArray !== undefined ) {
 
-			const index = listenerArray.indexOf( listener );
+			/* const index = listenerArray.indexOf( listener );
 
 			if ( index !== - 1 ) {
 
 				listenerArray.splice( index, 1 );
 
-			}
+			} */
+
+            let item = listenerArray.find(e=>e.listener == listener)
+            item && listenerArray.splice(listenerArray.indexOf(item), 1);
 
 		}
 
 	},
     removeEventListeners(type){//add
-		if(this._listeners[type] !== undefined){
+		if(this._listeners && this._listeners[type] !== undefined){
 			delete this._listeners[type];
 		}
 	} ,
@@ -270,8 +273,10 @@ Object.assign( EventDispatcher.prototype, {
     
     
     
-	dispatchEvent: function ( event ) {
-
+	dispatchEvent: function ( event ) { 
+        if(typeof event == 'string'){//add
+            event = {type:event}
+        }
 		if ( this._listeners === undefined ) return;
 
 		const listeners = this._listeners;
@@ -282,12 +287,12 @@ Object.assign( EventDispatcher.prototype, {
 			event.target = this;
 
 			// Make a copy, in case listeners are removed while iterating.
-			const array = listenerArray.slice( 0 );
-
-			for ( let i = 0, l = array.length; i < l; i ++ ) {
-
-				array[ i ].call( this, event );
-
+			 
+            for(let {listener} of listenerArray.slice(0)){
+				let result = listener.call(this, event);   //add stopContinue
+                if(result && result.stopContinue){
+                    break
+                }
 			}
 
 		}

+ 41 - 15
libs/three.js/lines/LineMaterial.js

@@ -3,7 +3,8 @@ import {
 	ShaderMaterial,
 	UniformsLib,
 	UniformsUtils,
-	Vector2
+	Vector2,
+    Color
 } from '../build/three.module.js';
 
 /**
@@ -27,8 +28,15 @@ UniformsLib.line = {
 	dashScale: { value: 1 },
 	dashSize: { value: 1 },
 	dashOffset: { value: 0 },
-	gapSize: { value: 1 }, // todo FIX - maybe change to totalSize
+	gapSize: { value: 1 }, 
 	opacity: { value: 1 },
+     
+    backColor:     {type:'v3',   value: new Color("#ddd")},
+    clipDistance :          { type: 'f', 	value:  4}, //消失距离
+    occlusionDistance :     { type: 'f', 	value:  1 }, //变为backColor距离
+    maxClipFactor :         { type: 'f', 	value:  1 },  //0-1
+    
+    
     
     depthTexture:{ value: null },
     nearPlane:{value: 0.1},
@@ -53,7 +61,8 @@ ShaderLib[ 'line' ] = {
 
 		uniform float lineWidth;
 		uniform vec2 resolution;
-
+        
+        
 		attribute vec3 instanceStart;
 		attribute vec3 instanceEnd;
 
@@ -196,7 +205,10 @@ ShaderLib[ 'line' ] = {
 		`
 		uniform vec3 diffuse;
 		uniform float opacity;
-
+        uniform vec3 backColor;
+        uniform float occlusionDistance;
+        uniform float clipDistance;
+        uniform float maxClipFactor;
 		#ifdef USE_DASH
 
 			uniform float dashSize;
@@ -280,14 +292,13 @@ ShaderLib[ 'line' ] = {
 
                 float textureDepth = convertToLinear(texture2D(depthTexture, depthTxtCoords).r);
 
-                float delta = textureDepth - fragDepth;
+                float delta = fragDepth - textureDepth;
 
-                if (delta < 0.0)
+                if (delta > 0.0)
                 {
-                    float occlusionDistance = - 1.0;
-                    float clipDistance = - 4.0;
+                    
                     mixFactor = clamp(delta / occlusionDistance, 0.0, 1.0);
-                    clipFactor = clamp(delta / clipDistance, 0.0, 1.0);
+                    clipFactor = clamp(delta / clipDistance, 0.0, maxClipFactor);
                 }
                  
                 if (clipFactor == 1.0)
@@ -295,18 +306,18 @@ ShaderLib[ 'line' ] = {
                     discard;
                 }
                 
-                vec4 backColor = vec4(0.8,0.8,0.8, 0.8*opacity);
+                vec4 backColor_ = vec4(backColor, opacity); //vec4(0.8,0.8,0.8, 0.8*opacity);
                  
                 #ifdef DASH_with_depth  
-                    // 只在被遮住的部分显示虚线
-                    if(unvisible) backColor.a = 0.0;
+                    // 只在被遮住的部分显示虚线, 所以若同时是虚线不可见部分和被遮住时, a为0
+                    if(unvisible) backColor_.a = 0.0;
                 #endif 
                 
-                //vec4 diffuseColor = vec4(mix(diffuse, backColor, mixFactor), opacity*(1.0 - clipFactor));
+                //vec4 diffuseColor = vec4(mix(diffuse, backColor_, mixFactor), opacity*(1.0 - clipFactor));
                
                
                
-                diffuseColor = mix(diffuseColor, backColor , mixFactor);   
+                diffuseColor = mix(diffuseColor, backColor_ , mixFactor);   
                
                
                 diffuseColor.a *= (1.0 - clipFactor);  
@@ -349,7 +360,22 @@ var LineMaterial = function ( parameters ) {
     
 	this.dashed = false;
     this.lineWidth_ = 0
-   
+    if(parameters.color){
+        this.color = new Color(parameters.color)  
+    }
+    if(parameters.backColor){
+        this.uniforms.backColor.value = new Color(parameters.backColor)
+    }
+    if(parameters.clipDistance){
+        this.uniforms.clipDistance.value = parameters.clipDistance
+    }
+    if(parameters.occlusionDistance){
+        this.uniforms.occlusionDistance.value = parameters.occlusionDistance
+    }
+    if(parameters.maxClipFactor){
+        this.uniforms.maxClipFactor.value = parameters.maxClipFactor
+    }
+    
    
 
 	Object.defineProperties( this, {

+ 89 - 43
note笔记笔记笔记.txt

@@ -5,7 +5,9 @@ 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
+navvis官网?
+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
@@ -21,7 +23,7 @@ http://indoor.popsmart.cn:8084/sxswsw-sx/?vlon=5.25&vlat=0.03&fov=100.0&pc=true&
 t-CwfhfqJ 大佛 有平面图 
 t-e2Kb2iU 隧道 
 t-8KbK1JjubE  回家湘
-t-Y22JxCS7sP 小区
+t-Y22JxCS7sP 小区 (无pano)
 t-8BCqxQAr93 小会议室
 t-AY03FoVZhm 一楼      (编辑完空间模型的)
 t-GusppsiKEC 字节跳动楼外场景
@@ -30,10 +32,11 @@ SS-t-P6zBR73Gke 燃气站
 t-QaHxu5Nmn3 一楼门口
 t-5HxBflA 梁启超故居
 
+t-FhDWmV5xur 车库
 
 
-
-
+多数据集:
+SS-t-Gpnepyz1JI
 
 	--多楼层漫游点:
 
@@ -71,9 +74,13 @@ Aa123456
 优化:  |
 ---------
 加载深度图(因为一开始用的全景)( 用深度图来模拟全景漫游的mesh似乎行不通,因为是非线性的,但可以加载chunks,超低模,或者重写点云shader,改成mesh的,只加载到level3)
-setView 旋转改成4dkk那种
+ 
+该场景有很多小房间,而boundingsky很大,导致过渡像瞬间渐变
+https://laser.4dkankan.com/index.html?m=SS-irJmUUy86l#/  
+
+
 
-当距离很远的过渡可以考虑瞬间过渡
+当距离很远的过渡可以考虑瞬间过渡,否则会很奇怪
 
 热点和测量线可能需要再次矫正(尤其截图时尽量居中)
  
@@ -89,8 +96,7 @@ setView 旋转改成4dkk那种
 moveSpeed 、 地图的自适应缩放
 
 数据集校准最好能显示现在位移和旋转距离上次修改的总量
-
-手机的测量线marker太小很难拖拽
+ 
 点击测量线后,或执行了setView后,如果再次移动镜头或再次setView,要取消之前的setView
 
 刚开始加载高质量点云可以在rendertarget内。或者有没有办法加载了不绘制
@@ -103,6 +109,7 @@ clip没写完。如果按照房间显示点云的话。
  
  
 
+
 ---------
 Bug	|
 ---------
@@ -135,27 +142,16 @@ Bug	|
 导航在地图上的高度怎么定
  
  
- 
-
-
- 
- 
   
-
-
 ----
 
  
  
   
- 
  macbook触摸板的也没有检查。 还不知道navvis的表现如何
 
  
 
-
-试了下双指同时平移和缩放,结果太难了,做不到。但是三个指头平移可以。四指转三指为何漂移
-
  
  
 我的se打开是空白的!!连调试都不行。不过navvis也是空白
@@ -175,13 +171,12 @@ Bug	|
 偶现手机里测量线没marker  
 
 
-测量线的白色在地图上不明显
-
+ 
  
 手机打开全景图特别慢
 
   
-在坐标页面加放大镜
+在坐标页面加放大镜,场景的ray是最高密度吗
 ========================
  
 sitemodel 
@@ -193,14 +188,10 @@ sitemodel
 
   
 
-
-cursor总感觉应该打开。 但是会比较乱,而且用reticule也可以试探出。target比较重要,而非当前位置
+ 
 
 --------------------
  
-clip时根据显示的范围来显示列表
-
-
 
  this.setProjectedPanos({  在点云模式禁止,切换全景转动后会变白
 
@@ -212,42 +203,97 @@ clip时根据显示的范围来显示列表
 
 
 
-route反向后datasetId没反向。。。还有如果在地图上没有datasetID
+ 
+为什么分屏时clip的transfrom框在map区域也绘制了? 黑色线框是boxVolume里的,黄色线框居然不属于boxVolume
+如果数据集可以任意旋转,如何判断数据集和entity重叠体积?
+如何判断数据集是否和clipBox(任意旋转)相交
+1 使用node判断
+ 
 
+  
+
+ 
+ 
 
-加载平面图。
-根据楼层加载平面图,且只展示当前楼层的漫游点。漫游点怎么选取,会不会不小心到其他楼?marker全部展示会很多天花板都有
 
+
+
+
+端点拖动时最好能切换成着附在点云上。或者在有点云时着附在点云上
+
+ 
+
+http://localhost:8080/index.html?m=t-8KbK1JjubE&test#/space-division    
+点云t-8KbK1JjubE_U1 发现都是0,0,-1  在数据集校准显示不出来
+还有一次boudingbox显示错误。导致居中不了
+
+  
+
+ 
+粒子的剪裁 和 lod
+  
+ 
+检查 hole没有点时,离开的话,hole会被删除吗
  
  
-数据集右上方的改彩色  地理注册
+卡顿 
 
+给大场景的热点也写一个isInsideFrustum
 
+ 
+  
+加载平面图:根据所在的楼层(如果多个楼层重叠,只算找到的第一个楼层),找出它所包含的全部数据集(重合体积占数据集体积10%以下的不算),加载这部分平面图。
+	或者随同漫游点,显示了的漫游点所在的数据集的平面图显示	
 
-火场轨迹和宽度
+	如果不在任何一个楼层,就不加载平面图?(navvis不加载)也可以加载最近层的平面图(如比最低层低就保留最低层,比最高层高就保留最高层,否则就是中间层的)
 
+	直接根据显示的漫游点的楼层吧
 
-removeMarker 等 dispose时, 要removeAllListeners 还有所有其他的侦听
-还有不可见时 比如RouteGuider
 
+test20220429-12:30
+test20220429-18:30
 
+ 
 
-把dispatchEvent简单写下,即使第一个就传type也能运行
 
+SS-t-Tbb9PpkNzd  三个数据集 但也不是很大吧 为什么这么卡?
 
 
 
-给你整理下现在三种火的类型参数:
-1 火焰:
-	颜色、 直径(宽度)、 高度、  密度百分比
-2 烟:(随着火添加)
-	颜色(黑色程度)、 直径 、速度(能影响高度)、 密度百分比
-3 爆炸:(另外添加)
-	 间隔时间、  直径、 密度百分比
+
+用boundingbox来判断数据集在哪个空间的话,对于参差不齐的数据集叠成的楼层,算不准。比如框柱的是数据集的上部,这个地方点云,明显很少,但算出的和下部的体积是一致的。
+用node会好些吗? 不过这种情况可能不多见。
+
+
+
+拖拽后取消选中marker
+
+
+updatclose 改为 raycaster  marker
+ 
+
+  
+突然发现小地图一放大就自动切换到点云模式了!
+ 
+
+ 
+不支持depth的可以直接depthTest : true吗
+ floor的box也改下
+
+
+
+
+room绘制、添加后删除 报错,等待修复
+
+感觉floor的depthMAterail没效果  
+
+
+floor
+
 
 
 
 
 
-端点拖动时最好能切换成着附在点云上。或者在有点云时着附在点云上
 
+if(viewport.alignment && handleState && viewport.alignment[handleState])  移动到alignment里吧 

+ 36 - 39
src/PointCloudOctree.js

@@ -347,7 +347,7 @@ export class PointCloudOctree extends PointCloudTree {
     
     
     
-    buildTexMesh(geometryNode,sceneNode){
+    buildTexMesh11(geometryNode,sceneNode){
         //  viewer.scene.pointclouds.forEach(a=>a.areaPlanes.forEach(e=>e.material = viewer.images360.cube.material))  
         //还是无法避免不在同一个平面的点被识别到同一个面上,然后法向都算错了。  另外还有就是破面太多。虽然能算出地板也不错。或者只去算水平面和垂直面。
         let startTime = Date.now()
@@ -688,15 +688,23 @@ export class PointCloudOctree extends PointCloudTree {
         
         
         
-        //-----------以下作废======================-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
-        
-        
-        
         
         
         
+        //------------------
+        /*        
+
+            viewer.scene.pointclouds[0].spriteNodeRoot.traverse(e=>e.material && (e.material = viewer.images360.cube.material))
+            viewer.scene.scene.children[12].visible = false
+                 
+         */
+
+
+    }    
+    
+    buildTexMesh(geometryNode,sceneNode){
         
-        if(geometryNode.level <= -1){ 
+        if(geometryNode.level <= 0){ 
             let startTime = Date.now()
             let splitSprites = new THREE.Object3D
             splitSprites.name = 'splitSprites_'+geometryNode.name
@@ -715,13 +723,13 @@ export class PointCloudOctree extends PointCloudTree {
             
             
             
-            const removeChip = true
+            const removeChip = false
             
             
             let geometry = geometryNode.geometry
             let count = geometry.attributes.position.count
             
-            count = 1000
+            //count = 4000
             
             
             let position = geometry.attributes.position.array
@@ -746,16 +754,7 @@ export class PointCloudOctree extends PointCloudTree {
             let closeGroups = []
             let groupTolerateMaxPoint = 4//组内点<=这个数的最后会被删除
             let removedCount = 0
-            
-            
-            
-            
-            
-            
-            
-            
-            
-            
+             
             
             for(i=0;i<count;i++){
                 let pos = new THREE.Vector3(position[3*i], position[3*i+1], position[3*i+2] );
@@ -808,7 +807,7 @@ export class PointCloudOctree extends PointCloudTree {
             for(i=0;i<count;i++){
                 let pos = positions[i]
                 let nor = normals[i]
-                 
+                if(Math.abs(nor.z)>0.2)continue 
                     
                 if(removeChip){  
                     if(pos.belongTo.length <= groupTolerateMaxPoint){
@@ -903,26 +902,10 @@ export class PointCloudOctree extends PointCloudTree {
         } 
         
         
+    }    
         
         
         
-        
-        
-        
-        
-        
-        //------------------
-        /*        
-
-            viewer.scene.pointclouds[0].spriteNodeRoot.traverse(e=>e.material && (e.material = viewer.images360.cube.material))
-            viewer.scene.scene.children[12].visible = false
-                 
-         */
-
-
-    }    
-    
-    
     
 
 	updateVisibleBounds () {
@@ -1808,7 +1791,7 @@ export class PointCloudOctree extends PointCloudTree {
 	}
     
     // 设置点大小
-    changePointSize(num) {
+    changePointSize(num, sizeFitToLevel) {
         
         if (num == void 0) {
             num = this.temp.pointSize
@@ -1816,7 +1799,7 @@ export class PointCloudOctree extends PointCloudTree {
             this.temp.pointSize = num
         }
         
-        if(Potree.settings.sizeFitToLevel){//按照点云质量来调整的版本:
+        if(sizeFitToLevel || Potree.settings.sizeFitToLevel){//按照点云质量来调整的版本:
             let base = this.material.spacing / Math.pow(2, this.maxLevel) //点云大小在level为0时设置为spacing,每长一级,大小就除以2
             base *= this.nodeMaxLevel > 0 ? Math.max(0.1, Math.pow(this.maxLevel / this.nodeMaxLevel, 1.3)) : 0.1 //低质量的缩小点,因为视觉上看太大了。navvis是不铺满的,我们也留一点缝隙
 
@@ -1904,7 +1887,21 @@ export class PointCloudOctree extends PointCloudTree {
                 new THREE.Vector3(bound.max.x, bound.max.y,0),
                 new THREE.Vector3(bound.min.x, bound.max.y,0),
             ].map(e=>e.applyMatrix4(this.matrixWorld)) 
-    }
+    } 
+    
+    
+    
+    ifContainsPoint(pos){
+        if(!this.bound.containsPoint(pos))return
+        var points = this.getUnrotBoundPoint()
+        return math.isPointInArea(points, null, pos)  
+    } 
+     
+    getVolume(){
+        var points = this.getUnrotBoundPoint()
+        var area = Math.abs(math.getArea(points))
+        return area * (this.bound.max.z - this.bound.min.z)
+    } 
      
     
     //数据集的显示影响到其下的:点云、marker  .不会影响地图上的显示

+ 1 - 1
src/Potree.js

@@ -199,7 +199,7 @@ export async function loadMapEntity(datasetId, force){
         var map = viewer.mapViewer.mapLayer.addMapEntity(data.data || data,  dataset_id)
         
         loaded ++; 
-    }
+    } 
     
     needLoads.forEach(dataset_id=>{
         let floorplanType = Potree.settings.floorplanType[dataset_id]

+ 1 - 1
src/materials/PointCloudMaterial.js

@@ -645,7 +645,7 @@ export class PointCloudMaterial extends THREE.RawShaderMaterial {
         
 		if (this._pointSizeType !== value) {
 			this._pointSizeType = value;
-			this.updateShaderSource();
+			this.updateShaderSource();              //这句表明这个属性频繁更改会卡顿
 			this.dispatchEvent({
 				type: 'point_size_type_changed',
 				target: this

+ 41 - 34
src/modules/Images360/Images360.js

@@ -54,7 +54,6 @@ export class Images360 extends THREE.EventDispatcher{
         //this.node2 = new THREE.Object3D();
         
      
-         
         
          
         this.cube = new THREE.Mesh(new THREE.BoxBufferGeometry(1,1,1,1),cm);
@@ -135,9 +134,7 @@ export class Images360 extends THREE.EventDispatcher{
                 return viewer.mapViewer.dispatchEvent(e/* {type:'global_click',e } */) 
             }
             
-            
-            
-            
+             
             if(Potree.settings.unableNavigate || this.flying  || !e.isTouch && e.button != THREE.MOUSE.LEFT || e.drag &&  e.drag.object)return //拖拽结束时不算
              
             /* if(currentlyHovered && currentlyHovered.pano){
@@ -295,7 +292,7 @@ export class Images360 extends THREE.EventDispatcher{
                          
                         
                         viewer.scene.pointclouds.forEach(e=>{
-                            viewer.updateVisible(e, 'displayMode', config2.showPoint) 
+                            viewer.updateVisible(e, 'displayMode', config2.showPoint, 2 ) 
                         })
                         this.cube.visible = config2.showSkybox
                         if(config2.pointUsePanoTex){  
@@ -336,10 +333,11 @@ export class Images360 extends THREE.EventDispatcher{
                         if(mode == 'showPanos'){  
                             camera.far = viewer.farWhenShowPano  //修改far
                             Potree.settings.pointDensity = 'panorama'
-                            
-                            viewer.scene.pointclouds.forEach(e=>{
-                                e.material.pointSizeType = 'FIXED'   
-                            })
+                            if(Potree.config.displayMode.showPanos.transition.pointUsePanoTex){
+                                viewer.scene.pointclouds.forEach(e=>{
+                                    e.material.pointSizeType = 'FIXED'   
+                                })
+                            } 
                             this.updateCube(this.currentPano)
                             
                         }else{
@@ -347,10 +345,11 @@ export class Images360 extends THREE.EventDispatcher{
                             Potree.settings.pointDensity = Potree.settings.UserPointDensity   
 
                             //Potree.sdk && Potree.sdk.scene.changePointOpacity() 
-                            viewer.scene.pointclouds.forEach(e=>{
-                                e.material.pointSizeType = Potree.config.material.pointSizeType
-                            })
-                            
+                            if(Potree.config.displayMode.showPanos.transition.pointUsePanoTex){
+                                viewer.scene.pointclouds.forEach(e=>{
+                                    e.material.pointSizeType = Potree.config.material.pointSizeType
+                                })
+                            }
                         }   
                         camera.updateProjectionMatrix() 
                         
@@ -362,7 +361,7 @@ export class Images360 extends THREE.EventDispatcher{
                         }
                          
                          
-                        //this.dispatchEvent({type:'endChangeMode',mode})  
+                        this.dispatchEvent({type:'endChangeMode',mode})  
                         console.log('setModeSuccess: ' + mode)       
                     }else{
                         
@@ -588,17 +587,16 @@ export class Images360 extends THREE.EventDispatcher{
         }
         
         let target = toPano.target 
-        let easeName = toPano.easeName || 'easeInOutQuad'
+        let easeName = toPano.easeName || 'easeInOutQuad' // 'easeInOutSine'//'easeOutSine' 
         
         let config = Potree.config.displayMode[Potree.settings.displayMode]
         var pointcloudVisi = config.atPano.showPoint  //viewer.scene.pointclouds[0].visible
         
         
         var pano = toPano.pano 
-        
-        
-        var duration = toPano.duration == void 0 ? (300+Math.min(Potree.config.transitionsTime.flyTime * this.position.distanceTo(pano.position),  Potree.config.transitionsTime.panoToPano )) : toPano.duration 
-        
+        let maxTime = this.isAtPano() ? Potree.config.transitionsTime.panoToPanoMax : Potree.config.transitionsTime.flyIn 
+        var duration = toPano.duration == void 0 ? (100+Math.min(Potree.config.transitionsTime.flyTime * this.position.distanceTo(pano.position),   maxTime)) : toPano.duration 
+        toPano.duration = duration
         //console.warn("flyto "+pano.id + ' duration: ' + duration )     
         
         this.nextPano = pano
@@ -653,7 +651,7 @@ export class Images360 extends THREE.EventDispatcher{
         
         
         const endPosition = pano.position.clone() 
-        this.flying = true
+        
         
         {
             toPano.duration = duration
@@ -662,7 +660,7 @@ export class Images360 extends THREE.EventDispatcher{
         }
         
         
-        viewer.scene.view.setView({position:endPosition, target ,duration,  
+        viewer.scene.view.setView({position:endPosition, target, quaternion:toPano.quaternion , duration,  
             callback:()=>{ 
                 
                 if(!config.atPano.pointUsePanoTex){ 
@@ -695,7 +693,7 @@ export class Images360 extends THREE.EventDispatcher{
             Easing:easeName  
         })
         
-        
+        this.flying = true  //写在setView,防止cancel其他项目导致flying为false
     }
 
 
@@ -787,7 +785,7 @@ export class Images360 extends THREE.EventDispatcher{
         
         let newCamPos = pano.position.clone()
         let target = newCamPos.clone().add(viewer.scene.view.direction)  
-        this.flying = true
+        
         
 		viewer.scene.view.setView( {position:newCamPos,  target, duration:dur ,
             callback:()=>{//done 
@@ -809,7 +807,7 @@ export class Images360 extends THREE.EventDispatcher{
             cancelFun:()=>{this.flying = false}  
         })
 
-		
+		this.flying = true
 
 		this.elUnfocus && (this.elUnfocus[0].style.display = "");
 	}
@@ -925,8 +923,8 @@ export class Images360 extends THREE.EventDispatcher{
 
     bump(direction) {//撞墙弹回效果
         if (!this.flying) {  
-            this.flying = true
             
+            console.log('bump')
             let distance = Potree.settings.displayMode == 'showPanos' ? 0.4 : 0.2;//感觉点云模式比全景模式更明显,所以降低
             let currentPos = this.position.clone()
             let endPosition = new THREE.Vector3().addVectors(this.position, direction.clone().multiplyScalar(distance)) 
@@ -941,11 +939,14 @@ export class Images360 extends THREE.EventDispatcher{
                         }, 
                         Easing:'easeInOutSine',
                         cancelFun:()=>{this.flying = false}
-                    }) 
+                    })
+                    this.flying = true  
                 }, 
+                
                 cancelFun:()=>{this.flying = false},  
                 Easing:'easeInOutSine'
-            })            
+            })  
+            this.flying = true        
         }
         //备注:将4dkk中的‘前后方向变化fov、左右方向移动镜头’ 都改为移动镜头。 因为这里无法判断左右离壁距离。
  
@@ -1121,7 +1122,6 @@ export class Images360 extends THREE.EventDispatcher{
             }
         })
         //return vectorForwards[0].direction
-        
          
         
         return {
@@ -1712,8 +1712,9 @@ export class Images360 extends THREE.EventDispatcher{
 Images360.prototype.checkAndWaitForPanoLoad = function() {
     var isLoadedPanos = {},
         LoadedTimePanos = {},
+        loadedCallback = {}, //add
         maxTime = 5e3;
-    var overtime = function() {
+    var withinTime = function() {
         for (var panoId in isLoadedPanos)
             if (isLoadedPanos.hasOwnProperty(panoId) && isLoadedPanos[panoId]) {
                 var differTime = performance.now() - LoadedTimePanos[panoId];
@@ -1724,13 +1725,19 @@ Images360.prototype.checkAndWaitForPanoLoad = function() {
     }
     
     return function(pano, basePanoSize, doneFun1, doneFun2, progressCallback, iswait, isclear, p   ) {
-        if (overtime())
-            return !0;
-   
+        loadedCallback[pano.id] = doneFun1//add 因为有可能之前请求的没加doneFun1, 如果加载好就执行最新的doneFun1
+        
+        if (withinTime()){//距离上次请求时间很近
+             
+            return !0;    //这里感觉应该是!1
+        }
+        
+        
+        
         var callback1 = (param1, param2)=>{ 
             setTimeout(()=>{
                 isLoadedPanos[pano.id] = !1;
-                doneFun1 && doneFun1(param1, param2); 
+                loadedCallback[pano.id] && loadedCallback[pano.id](param1, param2); 
             },1)
         } 
 
@@ -1746,7 +1753,7 @@ Images360.prototype.checkAndWaitForPanoLoad = function() {
             null !== iswait && void 0 !== iswait || (iswait = !0);
              
             isLoadedPanos[pano.id] = this.checkAndWaitForTiledPanoLoad(pano, basePanoSize, callback1, callback2, progressCallback, iswait, isclear, p   );
-             
+            //true代表没加载好
             isLoadedPanos[pano.id] && (LoadedTimePanos[pano.id] = performance.now());
             return isLoadedPanos[pano.id];
         } catch (msg) {

+ 4 - 3
src/modules/Images360/Panorama.js

@@ -65,11 +65,12 @@ class Panorama extends THREE.EventDispatcher{
         this.originFloorPosition = new THREE.Vector3().fromArray(o.dataset_floor_location)
         
         this.originID = parseInt(o.file_id)//"file_id":"00022"对应是原本的4dkk的id --来自vision.txt
-        
-        
-        
+         
         this.pointcloud = viewer.scene.pointclouds.find(e=>e.dataset_id == o.dataset_id) || viewer.scene.pointclouds[0]
         this.pointcloud.panos.push(this)
+        
+        this.sid = this.pointcloud.sceneCode + '|' + this.originID  //不会更改的标记
+        
         /* this.pointcloud.addEventListener('isVisible',(e)=>{ 
              
             var visible = viewer.getObjVisiByReason(this.pointcloud, 'datasetSelection')

+ 79 - 30
src/modules/siteModel/BuildingBox.js

@@ -6,6 +6,7 @@ import math  from "../../utils/math";
 import Sprite from '../../objects/Sprite'
 /* import {config} from '../settings' */
 import searchRings from "../../utils/searchRings.js";
+import DepthBasicMaterial from "../../materials/DepthBasicMaterial.js";
 
 let texLoader = new THREE.TextureLoader() 
 
@@ -33,56 +34,83 @@ let getFaceMat = (name)=>{
                 side:THREE.DoubleSide, 
                 opacity:0.1,
                 transparent:true,  
-                depthTest:false
+                depthTest:true
             }),
             buildingSelect: new THREE.MeshStandardMaterial({
                 color:36582,  metalness: 0, roughness:1,
                 side:THREE.DoubleSide,
                 opacity:0.1,
                 transparent:true,
-                depthTest:false
+                depthTest:true
             }),
             floor:  new THREE.MeshStandardMaterial({
                 color:11708469,  metalness: 0.1, roughness:1,
                 side:THREE.DoubleSide,//BackSide,
                 opacity:0.05,
                 transparent:true,
-                depthTest:false
+                depthTest:true, 
             }),
-            /* floorSelect: new THREE.MeshStandardMaterial({
-                color:"#eeee00",  metalness: 0, roughness:1,
-                side:THREE.DoubleSide,
-                opacity:0.12,
-                transparent:true,
-                depthTest:false
-            }), */
              
-            floorSelect: new THREE.MeshStandardMaterial({
+            /* floorSelect: new THREE.MeshStandardMaterial({
                 color:16707151,  metalness: 0, roughness:1,
                 side:THREE.DoubleSide,
                 opacity:1,
                 transparent:true,
-                depthTest:false,
+                depthTest:true,
+                polygonOffset : true,//是否开启多边形偏移 
+				polygonOffsetFactor : -0.75,//多边形偏移因子
+				polygonOffsetUnits : -4.0,//多边形偏移单位 
                 map: gridTex,
-            }), 
-            
+            }),  */ 
+            floorSelect: new DepthBasicMaterial({
+                map: gridTex,
+                color:16707151,  
+                side:THREE.DoubleSide,//BackSide, 
+                opacity:1,
+                transparent:true, 
+                useDepth : true,
+                /* polygonOffset : true,//是否开启多边形偏移 
+				polygonOffsetFactor : -0.75,//多边形偏移因子
+				polygonOffsetUnits : -4.0,//多边形偏移单位  */
+                
+                clipDistance : 1, occlusionDistance:1, /* occlusionDistance:变为backColor距离, clipDistance:opacity到达0或者1-maxClipFactor时的距离 */  
+                maxClipFactor:0.6, backColor:"#669988"  ,
+                  
+            }),
             
             room: new THREE.MeshStandardMaterial({
                 color:"#ff44ee",  metalness: 0, roughness:1,
                 side:THREE.DoubleSide,//BackSide,
                 opacity:0.08,
-                transparent:true,
-                depthTest:false
+                transparent:true, 
+                depthTest:false, 
             }),
-            roomSelect: new THREE.MeshStandardMaterial({
+            /* roomSelect: new THREE.MeshStandardMaterial({
                 color:"#ff44ee",  metalness: 0.3, roughness:1,
                 side:THREE.DoubleSide,//BackSide,
                 opacity:1,
                 transparent:true,
-                depthTest:false,
+                depthTest:true,
+                polygonOffset : true,//是否开启多边形偏移.(开启是因为和floor重叠了会闪烁)
+				polygonOffsetFactor : -0.75,//多边形偏移因子
+				polygonOffsetUnits : -4.0,//多边形偏移单位  
                 map: gridTex,
-            }),
-            
+            }), */
+            roomSelect: new DepthBasicMaterial({
+                map: gridTex,
+                color:"#ff44ee", 
+                side:THREE.DoubleSide,//BackSide, 
+                opacity:1,
+                transparent:true, 
+                useDepth : true,
+                /* polygonOffset : true,//是否开启多边形偏移 
+				polygonOffsetFactor : -0.75,//多边形偏移因子
+				polygonOffsetUnits : -4.0,//多边形偏移单位  */
+                
+                clipDistance : 1, occlusionDistance:0.5, /* occlusionDistance:变为backColor距离, clipDistance:opacity到达0或者1-maxClipFactor时的距离 */  
+                maxClipFactor:0.85, backColor:"#cc99c2"  ,
+                 
+            })
         }
     }
     return faceMats[name]
@@ -201,7 +229,7 @@ export class BuildingBox extends ctrlPolygon{//建筑实体,包括building, fl
         
         if(holes.length>0){//还要再扣除holes与数据集重叠的部分。其中holes为mix轮廓
             let outHoles = []//没有重合的holes的外轮廓
-            if(holes.length>=2){//合并holes。如果能在绘制时直接合并holes就好啦,这步就转移到那去,但是要删除hole好麻烦
+            /* if(holes.length>=2){//合并holes。如果能在绘制时直接合并holes就好啦,这步就转移到那去,但是要删除hole好麻烦
                   
                 let holes_ = holes.map(e=>e.points)
                 
@@ -215,7 +243,8 @@ export class BuildingBox extends ctrlPolygon{//建筑实体,包括building, fl
             }else{
                 outHoles = holes.map(e=>e.points)
                 outHoles.forEach(e=> holesArea += Math.abs(math.getArea(e)))                
-            }
+            } */
+            holesArea = this.getHolesArea()
             
             //holes与数据集重叠的部分
             
@@ -459,15 +488,15 @@ export class BuildingBox extends ctrlPolygon{//建筑实体,包括building, fl
     updateBox(){
         if(!this.box)return
         this.box.geometry.dispose()
-        
+        var shrink = this.buildType == 'floor' ? 0.0032 : 0.0073;//防止mesh重叠冲突(给一个不寻常的数字
         if(this.points.length >= 3){ 
             let holes = this.holes.concat(this.parentHoles)
             let holesPoints = holes.filter(e=>e.points.length>2).map(e=>e.points)
             this.box.geometry = MeshDraw.getExtrudeGeo(this.points, holesPoints, {
-                depth:this.zMax-this.zMin,
+                depth:this.zMax-this.zMin-shrink,
                 UVGenerator: new MetricUVGenerator()
             }) 
-            this.box.position.z = this.zMin
+            this.box.position.z = this.zMin + shrink / 2  
         }
     }
     
@@ -556,18 +585,38 @@ export class BuildingBox extends ctrlPolygon{//建筑实体,包括building, fl
     
     
     
+    getHolesArea(){
+        let holes = this.holes.concat(this.parentHoles)
+        let outHoles, holesArea = 0
+        if(holes.length>=2){//合并holes。如果能在绘制时直接合并holes就好啦,这步就转移到那去,但是要删除hole好麻烦
+              
+            let holes_ = holes.map(e=>e.points)
+            
+            outHoles = math.getPolygonsMixedRings(holes_,  true )
+            outHoles.forEach(e=>{ 
+                holesArea+=e.area
+            }) 
+            outHoles = outHoles.map(e=>e.points)
+            
+            
+        }else{
+            outHoles = holes.map(e=>e.points)
+            outHoles.forEach(e=> holesArea += Math.abs(math.getArea(e)))                
+        }
+        return holesArea
+        
+    }
     
-    
-    getArea(){//面积
+    getArea(ifRidOfHoles){//面积
         //不排除hole
-        return Math.abs(math.getArea(this.points))
+        return Math.abs(math.getArea(this.points)) - (ifRidOfHoles ? this.getHolesArea() : 0)
     }
     
-    getVolume(){//体积
+    getVolume(ifRidOfHoles){//体积
         let {zMin , zMax} = this.getRealZ()
         let height = zMax - zMin;
         if(isNaN(height))height = 0
-        return this.getArea() * height
+        return this.getArea(ifRidOfHoles) * height
     
     }
     

+ 120 - 16
src/modules/siteModel/SiteModel.js

@@ -119,20 +119,79 @@ var SiteModel = {
         
     },
 
+
+    updateCadVisibles(floor){
+        var visiClouds = this.floorplansVisi = floor ? findDatasetsAtFloor(floor) : []
+         
+        viewer.scene.pointclouds.forEach(e=>{ 
+            var floorplan = viewer.mapViewer.mapLayer.getFloorplan(e.dataset_id)
+            var visi = visiClouds.includes(e) 
+            if(floorplan){
+                viewer.updateVisible(floorplan.objectGroup, 'buildingChange', visi) 
+            }else if(!visi){
+                let changeVisi = (e)=>{
+                    viewer.updateVisible(floorplan.objectGroup, 'buildingChange', this.floorplansVisi.includes(e)) 
+                    viewer.mapViewer.mapLayer.removeEventListener('floorplanLoaded',  changeVisi)
+                    console.log('updateCadVisibles加载后更改显示',e)
+                } 
+                viewer.mapViewer.mapLayer.addEventListener('floorplanLoaded',  changeVisi)
+            }         
+        })
+        viewer.mapViewer.mapLayer.needUpdate = true  
+        
+        function findDatasetsAtFloor(entity){//找当前楼层需要显示哪些数据集。
+            //必要条件: 如果数据集有漫游点的话,需要包含>20%的漫游点。   (防止重叠体积很大但其实一个漫游点都不包含)
+            //充分条件(在符合必要条件之后还应该满足至少一个充分条件): 重叠体积>50%   或   包含>50%的漫游点 
+            const ratio1 = 0.2, ratio2 = 0.5, ratio3 = 0.5
+            var pointclouds = viewer.scene.pointclouds.filter(e=>{
+                
+                if(e.panos.length){
+                    var insidePanos = e.panos.filter(a=>entity.ifContainsPoint(a.position));
+                    let panoCountRatio = insidePanos.length / e.panos.length
+                    if(panoCountRatio < ratio1){ 
+                        return false
+                    }
+                    
+                    if(panoCountRatio > ratio2)return true 
+                } 
+                 
+                 
+                let volume = entity.intersectPointcloudVolume(e);
+                let volumeRatio = volume / entity.getVolume(true) //注:hole加入计算
+                if(volumeRatio > ratio3){
+                    return true 
+                } 
+            })
+            return pointclouds
+        }
+    },
+    
+
+
+
+
     updatePanosVisible(lastEntity, entity, force){//根据所在楼层更新marker可见性。当在楼层中时,只显示当前楼层的marker。
-        if(!entity ){//暂定:不在任何一个实体中时显示全部漫游点
+        if(!entity ){//暂定:不在任何一个实体中时 显示全部漫游点(和平面图显示不同,平面图就一个都不显示) 
             viewer.images360.panos.forEach(pano=>{
                 viewer.updateVisible(pano, 'buildingChange', true)  
             })
+            /* //只显示当前数据集的  //但是需要改变位置就计算,太麻烦
+            var atPointcloud = viewer.pointInWhichPointcloud(viewer.images360.position)
+            atPointcloud && atPointcloud.panos.forEach(pano=>{
+                viewer.updateVisible(pano, 'buildingChange', true)  
+            }) */ 
+            this.updateCadVisibles(null)
         }else{
             let lastFloor = lastEntity ? lastEntity.buildType == 'floor' ? lastEntity : lastEntity.buildType == 'room' ? lastEntity.buildParent : null : null; //基本只会是floor或room
             let currentFloor = entity ? entity.buildType == 'floor' ? entity : entity.buildType == 'room' ? entity.buildParent : null : null; //基本只会是floor或room
             if(currentFloor != lastFloor || force){
-                console.log('改变了floor',lastFloor,currentFloor)
+                //console.log('改变了floor',lastFloor,currentFloor)
                 if(lastFloor){
                     lastFloor.panos.forEach(pano=>{
                         viewer.updateVisible(pano, 'buildingChange', false)  
                     })
+                     
+                    
                 }else{//重置为全部不可见
                     viewer.images360.panos.forEach(pano=>{
                         viewer.updateVisible(pano, 'buildingChange', false)  
@@ -142,9 +201,18 @@ var SiteModel = {
                     currentFloor.panos.forEach(pano=>{
                         viewer.updateVisible(pano, 'buildingChange', true)  
                     })
+                    
+                    this.updateCadVisibles(currentFloor)
+                    
+                    
+                    
                 }
 
             }
+            
+            
+            
+             
         } 
     },
 
@@ -939,7 +1007,9 @@ var SiteModel = {
         
         let lastResult; //最接近的上一层结果,如果没有result返回这个
         let result
-         
+        let level = {
+            building: 0, floor: 1, room: 2 
+        }
         
         let traverse = (parent)=>{
             let contains;
@@ -949,14 +1019,18 @@ var SiteModel = {
                 contains = parent.panos.includes(location)
             }
             if(contains){
-                lastResult = parent
+                if(!lastResult || level[lastResult.buildType] < level[parent.buildType]  )lastResult = parent
+                
+                
                 if(parent.buildType == buildType){
                     return parent
                 }else{  
                     for(let i=0,len=parent.buildChildren.length; i<len; i++){
-                        if(traverse(parent.buildChildren[i])){
+                        /* if(traverse(parent.buildChildren[i])){
                             return parent.buildChildren[i]
-                        } 
+                        } */ 
+                        let result1 = traverse(parent.buildChildren[i])
+                        if(result1) result1
                     }  
                 }
             }
@@ -1045,11 +1119,14 @@ var SiteModel = {
         
     }
     ,
-    findEntityForDataset:function(){
+    
+    
+    
+    findEntityForDataset:function(){//为每一个数据集寻找它所属的最小实体
         var entities = this.entities.filter(e=>e.buildType == 'room' || e.buildType == 'floor' && e.buildChildren.length == 0)
         viewer.scene.pointclouds.forEach(pointcloud=>{
              
-            let volumes = []
+            /* let volumes = []
             entities.forEach(entity=>{
                 let volume = entity.intersectPointcloudVolume(pointcloud)
                 volumes.push({entity, volume})
@@ -1060,14 +1137,36 @@ var SiteModel = {
                 pointcloud.belongToEntity = null
             }else{
                 pointcloud.belongToEntity = volumes[0].entity; 
-            }
+            } */
+            let cloudVolume = pointcloud.getVolume()
+            let scores = []
+            entities.forEach(entity=>{
+                let volume = entity.intersectPointcloudVolume(pointcloud) 
+                //注:默认已经findPanos过
+                let panos = entity.panos.filter(e=>pointcloud.panos.includes(e));
+                let panoCount = panos.length
+                
+                let score = volume / cloudVolume + panoCount / pointcloud.panos.length
+                 
+                scores.push({entity, volume, panoCount, score})
+ 
+            }) 
+            scores.sort((a,b)=>{ return b.score-a.score }) 
             
+            if(scores.length == 0 || scores[0].volume/cloudVolume < 0.02){//如果约等于0 
+                pointcloud.belongToEntity = null
+            }else{
+                pointcloud.belongToEntity = scores[0].entity; 
+            } 
         })
         
         /*
         只需要考虑 floor 和 room, 因为building的只有一个基底没高度
         floor 和 room 在空间中没有完全的从属关系,因为room可以超出floor之外。所以直接混在一起来查找,但要排除有房间的楼层。 
-        直接计算实体和点云的重叠体积 ,重叠体积大的最小实体将会拥有该点云。
+        
+        有的数据集虽然很高,但只有近地面的部分才是主体,这部分一般含有全部漫游点。为了防止上层的实体因体积较大而分数高,就把包含漫游点的个数也加入考虑。
+        
+        重叠体积大、且包含漫游点最多的最小实体将会拥有该点云。
         
         
         
@@ -1097,13 +1196,13 @@ var SiteModel = {
          
     }
     ,
-    gotoEntity(id, isNearBy) { 
+    gotoEntity(id, isNearBy, duration=1000) { 
         var entity = this.entities.find(e => e.sid == id)
         let aimPano
         if (!entity) {
             return console.error('没找到entity ')
         }
-       
+        
         if(Potree.settings.displayMode == 'showPanos'){
             if (isNearBy && entity.panos.length) {
                 if(entity.panos.includes(viewer.images360.currentPano)) return 'posNoChange' //已在当前实体中
@@ -1129,19 +1228,24 @@ var SiteModel = {
 
             let boundingBox = entity.getBound()
             let position = boundingBox.getCenter(new THREE.Vector3())
-             
+            
             if(viewer.controls == viewer.orbitControls){ 
                 let dis = 2
                 let target = position
                 position = new THREE.Vector3().subVectors(target, viewer.scene.view.direction)
-                viewer.scene.view.setView({position,  duration: 1000,  target})
+                viewer.scene.view.setView({position,  duration,  target})
             }else{
                 if(math.closeTo(position, viewer.images360.position)) return 'posNoChange'  
+                let size = boundingBox.getSize(new THREE.Vector3())
 
-                viewer.scene.view.setView({position,  duration: 1000})
-            }
             
+                viewer.scene.view.setView({position,  duration})
+                viewer.mapViewer.moveTo(position, size, duration)
+                
+                
+            }
             
+             
             
             
         }

+ 2 - 1
src/navigation/InputHandler.js

@@ -703,7 +703,8 @@ export class InputHandler extends THREE.EventDispatcher {
             this.viewer.scene.pointclouds,
             {pickClipped: true, isMeasuring: this.isMeasuring, pickWindowSize}
         );
-            
+        
+           
         //console.log(viewport.name , intersectPoint &&  intersectPoint.location )
         
         if(viewport.camera.type == 'OrthographicCamera'/*  == 'mapViewport' */){ 

+ 18 - 8
src/objects/tool/Measure.js

@@ -22,6 +22,16 @@ var markerMats;
 var lineMats;  
 var planeMats 
 
+const lineDepthInfo = {
+    clipDistance : 4,//消失距离
+    occlusionDistance: 1,//变为backColor距离 
+}
+const LabelDepthInfo = {
+    clipDistance : 6,//消失距离
+    occlusionDistance: 2,//变为backColor距离 
+}
+
+
 const markerSizeInfo = {
     minSize : 25 ,  maxSize : 65,   nearBound : 0.2, farBound : 4,
 }
@@ -658,16 +668,16 @@ export class Measure extends ctrlPolygon{
     }
 
     
-    getMarkerMaterial(type) {
+    getMarkerMaterial(type) { 
         if(!markerMats){
             markerMats = {  
-                default:    new DepthBasicMaterial({  
+                default:    new DepthBasicMaterial($.extend({},lineDepthInfo,{ 
                     transparent: !0,
                     opacity: 1,
                     map: texLoader.load(Potree.resourcePath+'/textures/pic_point_s32.png' ), 
                     useDepth:true 
-                }),
-                select:    new DepthBasicMaterial({   
+                })),
+                select:    new THREE.MeshBasicMaterial({  
                     transparent: !0,
                     opacity: 1,
                     map: texLoader.load(Potree.resourcePath+'/textures/pic_point32.png'/* , null, null, { antialias: false } */), 
@@ -724,19 +734,19 @@ export class Measure extends ctrlPolygon{
     
     createAreaPlane(){
         planeMats || (planeMats = { 
-            default: new DepthBasicMaterial({
+            default: new DepthBasicMaterial( $.extend({},LabelDepthInfo,{
                 color:color,
                 side:THREE.DoubleSide,
                 opacity:0.2,
                 transparent:true,
                 useDepth:true 
-            }), 
-            selected: new DepthBasicMaterial({
+            })), 
+            selected: new THREE.MeshBasicMaterial({
                 color:color,
                 side:THREE.DoubleSide,
                 opacity:0.3,
                 transparent:true
-            }) 
+            })
         },Measure.planeMats = planeMats)
         return super.createAreaPlane(planeMats.default)
     }

+ 4 - 4
src/objects/tool/MeasuringTool.js

@@ -455,7 +455,7 @@ export class MeasuringTool extends THREE.EventDispatcher{
                 type : "CursorChange", action : "remove",  name:"polygon_AtWrongPlace"
             });
             
-            viewer.inputHandler.dispatchEvent('isMeasuring', {v:false, cause:'stopInsertion'}  ) 
+            viewer.inputHandler.dispatchEvent({type:'isMeasuring',  v:false, cause:'stopInsertion'}  ) 
             
             e.remove || callback && callback()  
             /* this.viewer.dispatchEvent({
@@ -566,14 +566,14 @@ export class MeasuringTool extends THREE.EventDispatcher{
         
         //点击第n下拥有n+1个marker, n>0
         
-        viewer.inputHandler.dispatchEvent('isMeasuring',{v: true, cause:'startInsertion'})
+        viewer.inputHandler.dispatchEvent({type: 'isMeasuring', v: true, cause:'startInsertion'})
         
         this.viewer.addEventListener('global_click', click, 10)//add importance:10
             
         let ifAtWrongPlace = (e)=>{
             if(measure.unableDragAtMap && e.hoverViewport.name == 'mapViewport' ){ 
                 if(e.isTouch){
-                    viewer.dispatchEvent('reticule_forbit', {v:true})
+                    viewer.dispatchEvent({type:'reticule_forbit', v:true})
                 }else{
                     viewer.dispatchEvent({
                         type : "CursorChange", action : "add",  name:"polygon_AtWrongPlace"
@@ -582,7 +582,7 @@ export class MeasuringTool extends THREE.EventDispatcher{
                 return true
             }else{ 
                 if(e.isTouch){
-                    viewer.dispatchEvent('reticule_forbit', {v:false})
+                    viewer.dispatchEvent({type:'reticule_forbit',v:false})
                 }else{
                     viewer.dispatchEvent({
                         type : "CursorChange", action : "remove",  name:"polygon_AtWrongPlace"

+ 13 - 3
src/objects/tool/mapClipBox.js

@@ -237,6 +237,7 @@ export class mapClipBox extends ctrlPolygon {
         })
         bar.position.set(0,lineLen+circleWidth/2,0)
         bar.scale.set(circleWidth,circleWidth,circleWidth)
+        
         bar.addEventListener('mouseover',()=>{
             bar.material.opacity = 1
             viewer.dispatchEvent({
@@ -244,13 +245,18 @@ export class mapClipBox extends ctrlPolygon {
             })
             viewer.mapViewer.dispatchEvent('content_changed') 
         })
-        bar.addEventListener('mouseleave',()=>{
+        
+        let leave = ()=>{ 
             bar.material.opacity = barOpacity
             viewer.dispatchEvent({
                 type : "CursorChange", action : "remove",  name:"mapClipRotate"
             })
             viewer.mapViewer.dispatchEvent('content_changed') 
-        })
+            
+        } 
+        bar.addEventListener('mouseleave',leave)
+        this.addEventListener('dispose', leave)    
+        
         let lastPos;
         bar.addEventListener('drag',(e)=>{
             var intersectPoint = e.intersectPoint.orthoIntersect   
@@ -308,7 +314,11 @@ export class mapClipBox extends ctrlPolygon {
         
     }
     
-    
+    dispose(){
+        super.dispose()
+        this.dispatchEvent('dispose')
+        
+    }
      
 }
 

+ 17 - 8
src/settings.js

@@ -25,9 +25,9 @@ const config = {//配置参数   不可修改
                 pointUsePanoTex : false  
 			},
             transition:{
-                showPoint: true,
+                //showPoint: true,
                 showSkybox: true,
-                pointUsePanoTex: true //是否使用全景贴图
+                //pointUsePanoTex: true //是否使用全景贴图
             },
             canLeavePano: false    
 		}, 
@@ -78,10 +78,10 @@ const config = {//配置参数   不可修改
         flyOut:1000,
     } */
     transitionsTime:{
-        flyTime : 2000,  // 毫秒/米
-        panoToPano: 1000, 
+        flyTime : 180,  // 毫秒/米
+        panoToPanoMax: 2000, 
         flyIn:1000,
-        flyOut:1000,
+        flyOut:1000
     }
     
     ,
@@ -105,8 +105,8 @@ const config = {//配置参数   不可修改
             pointBudget : 8*1000*1000, 
         },
         panorama:{//显示全景时的漫游。因为点只能显示1个像素的大小,所以必须很密集,但又要限制点的数量
-            maxLevelPercent: 1,
-            pointBudget : browser.isMobile() ?  0.1*1000*1000 :  0.25*1000*1000,  //点云总最大数
+            maxLevelPercent: 0.6,
+            pointBudget : /* 4*1000*1000// */browser.isMobile() ?  0.1*1000*1000 :  0.4*1000*1000,  //点云总最大数
         }, 
         fourViewports:{//分四屏时防止卡顿
             maxLevelPercent: 0.4,  
@@ -174,6 +174,12 @@ const config = {//配置参数   不可修改
         maxSize: 10000,
         pointSizeType: 'ATTENUATED', //'ADAPTIVE'//'ADAPTIVE' \ FIXED //ADAPTIVE的在小房间里大小会不太匹配,但在远景似乎更好
         absolutePanoramaSize: 1.3 ,//全景漫游时的size  是fixed的模式
+        
+        //sizeAtPanoRtEDL : 2000,  
+        
+        
+        
+        //sizeAddAtPanoRtEDL : 0.5, //全景模式静止时的size
         //ADAPTIVE : 字会失真扭曲
         //'ATTENUATED' 往旁边看有缝隙、点在浮动
         //navvis的shader在哪里 为什么不会抖动
@@ -360,7 +366,7 @@ let settings = {//设置   可修改
         max: config.highQualityMaxZoom,
         activationThreshold: 1.1,
     },
-    
+    navConstantly:true,
     navTileClass: browser.isMobile() ? '1k' : '2k',  //默认加载到
     tileClass:'4k',     //最高可达
     /* loadTilesWhenUnfocus:false, //页面unfocus时也仍在加载tiles
@@ -378,6 +384,9 @@ let settings = {//设置   可修改
     tourTestCameraMove:false, //测试镜头时,不移动真实的镜头, 只移动frustum
     cameraAniSmoothRatio : 20, //镜头动画平滑系数,越高越平滑
     urls  : $.extend({}, config.urls), 
+    
+    
+    
         
 }
 

+ 4 - 2
src/start.js

@@ -109,7 +109,9 @@ var start = function(dom, mapDom, number, fileServer, webSite){ //t-Zvd3w0m
                 } 
             }
             
-            viewer.addFire()
+            
+            
+            viewer.addVideo()//addFire()
             
             console.log('allLoaded')
             viewer.dispatchEvent('allLoaded')
@@ -162,7 +164,7 @@ var start = function(dom, mapDom, number, fileServer, webSite){ //t-Zvd3w0m
             viewer.mapViewer && viewer.mapViewer.mapLayer.maps[0].updateProjection()
             
         }
-        
+         
         
         data.forEach((dataset,index)=>{  
             if(!ifReload){

+ 126 - 77
src/utils/transitions.js

@@ -180,7 +180,7 @@ easing.easeInOutBounce = function(currentTime, startY, wholeY, r) {
 
 
 var lerp = {
-	vector: function(currentTime, startY, f) {//xzw change, add f
+	/* vector: function(currentTime, startY, f) {//xzw change, add f
 		var wholeY = currentTime.clone();
 		return startY = startY.clone(),
 		function(duration) {
@@ -230,6 +230,55 @@ var lerp = {
                 startY(currentTime)
             })
         }
+    } */
+    
+    
+    
+    vector: function(t, i, f) {//xzw change, add f
+        var n = t.clone();
+        return i = i.clone(),
+        function(e) {
+            t.set(n.x * (1 - e) + i.x * e, n.y * (1 - e) + i.y * e, n.z * (1 - e) + i.z * e)
+            f && f(t,e);
+        }
+    },
+    quaternion: function(t, i, f) {//xzw change, add f
+        var n = t.clone();
+        return function(e) {
+            t.copy(n).slerp(i, e)
+            f && f(t,e);
+        }
+    },
+    property: function(t, i, n, r) {
+        var o = t[i];
+        return function(e) {
+            t[i] = o * (1 - e) + n * e,
+            r && r(t[i])     
+        }
+    },
+    uniform: function(t, i, n) {
+        var r = t.material.uniforms[i].value;
+        return function(e) {
+            t.material.uniforms[i] && (t.material.uniforms[i].value = r * (1 - e) + n * e)
+        }
+    },
+    matrix4: function(o, a) {
+        var s = o.clone();
+        return function(e) {
+            for (var t = o.elements, i = s.elements, n = a.elements, r = 0; r < 16; r++)
+                t[r] = i[r] * (1 - e) + n[r] * e
+        }
+    },
+    allUniforms: function(e, t, i) {
+        var n = e.map(function(e) {
+            return this.uniform(e, t, i)
+        }
+        .bind(this));
+        return function(t) {
+            n.forEach(function(e) {
+                e(t)
+            })
+        }
     }
 };
  
@@ -248,42 +297,42 @@ var transitions = {
     funcs: [],
     counter: 0,
     uniqueID: 0,
-    start: function(currentTime, startY, wholeY, r, o, a, s, cancelFun) {
-        return r = r || 0,
+    start: function(func, duration, done, delay, ease, name, id, cancelFun) {
+        return delay = delay || 0,
         this.funcs.push({
-            func: currentTime,
-            current: -r * Math.abs(startY),                      //当前时间
-            duration: (1 - Math.max(r, 0)) * Math.abs(startY),   //总时长
-            done: wholeY,
-            easing: o || easing.linearTween,                //渐变曲线
-            cycling: startY < 0,
+            func: func,
+            current: -delay * Math.abs(duration),                      //当前时间
+            duration: (1 - Math.max(delay, 0)) * Math.abs(duration),   //总时长
+            done: done,
+            easing: ease || easing.linearTween,                //渐变曲线
+            cycling: duration < 0,
             running: !0,
-            debug: r < 0,
-            name: a || "startY" + this.counter,
-            id: void 0 === s ? this.counter : s,
+            debug: delay < 0,
+            name: name || "T" + this.counter,
+            id: void 0 === id ? this.counter : id,
             paused: !1,
 			cancelFun : cancelFun,   //取消时执行的函数
         }),
-        currentTime(0, 16),
+        func(0, 16),
         this.counter += 1,
-        currentTime
+        func
     },
-    trigger: function(currentTime) {
-        var startY = void 0 === currentTime.delayRatio ? 0 : currentTime.delayRatio
-            , wholeY = currentTime.func || function() {}
-            , r = void 0 === currentTime.duration ? 0 : currentTime.duration;
-        void 0 !== currentTime.cycling && currentTime.cycling && (r = -Math.abs(r));
-        var o = currentTime.done || null
-            , a = currentTime.easing || easing.linearTween
-            , s = currentTime.name || "R" + this.counter
-            , l = void 0 === currentTime.id ? this.counter : currentTime.id;
-        return this.start(wholeY, r, o, startY, a, s, l)
+    trigger: function(e) {
+        var t = void 0 === e.delayRatio ? 0 : e.delayRatio
+            , u = e.func || function() {}
+            , r = void 0 === e.duration ? 0 : e.duration;
+        void 0 !== e.cycling && e.cycling && (r = -Math.abs(r));
+        var o = e.done || null
+            , a = e.easing || easing.linearTween
+            , s = e.name || "R" + this.counter
+            , l = void 0 === e.id ? this.counter : e.id;
+        return this.start(u, r, o, t, a, s, l)
     },
-    setTimeout: function(currentTime, startY, wholeY) {
-        var duration = void 0 === wholeY ? this.counter : wholeY;
+    setTimeout: function(e, t, u) {
+        var duration = void 0 === u ? this.counter : u;
         return this.trigger({
-            done: currentTime,
-            duration: void 0 === startY ? 0 : startY,
+            done: e,
+            duration: void 0 === t ? 0 : t,
             name: "O" + this.counter,
             id: duration
         })
@@ -294,83 +343,83 @@ var transitions = {
     resume: function() {
         this.paused = !1
     },
-    update: function(currentTime) {
-        this.funcs.forEach(function(startY) {
-            if (!(startY.paused || (startY.current += 1e3 * currentTime,
-            startY.current < 0)))
-                if (startY.current >= startY.duration && !startY.cycling) {
-                    var wholeY = startY.easing(1, 0, 1, 1);
-                    startY.func(wholeY, 1e3 * currentTime),
-                    startY.done && startY.done(),
-                    startY.running = !1
+    update: function(e) {
+        this.funcs.forEach(function(t) {
+            if (!(t.paused || (t.current += 1e3 * e,
+            t.current < 0)))
+                if (t.current >= t.duration && !t.cycling) {
+                    var u = t.easing(1, 0, 1, 1);
+                    t.func(u, 1e3 * e),
+                    t.done && t.done(),
+                    t.running = !1
                 } else {
-                    var duration = startY.easing(startY.current % startY.duration / startY.duration, 0, 1, 1)
-                        , r = startY.func(duration, 1e3 * currentTime) || !1;
-                    r && (startY.done && startY.done(),
-                    startY.running = !1)
+                    var duration = t.easing(t.current % t.duration / t.duration, 0, 1, 1)
+                        , r = t.func(duration, 1e3 * e) || !1;
+                    r && (t.done && t.done(),
+                    t.running = !1)
                 }
         });
-        var startY = this.funcs.length;
-        this.funcs = this.funcs.filter(function(currentTime) {
-            return currentTime.running
+        var t = this.funcs.length;
+        this.funcs = this.funcs.filter(function(e) {
+            return e.running
         });
-        var wholeY = this.funcs.length;
-        if (startY > 0 && 0 === wholeY && this.globalDone) {
+        var u = this.funcs.length;
+        if (t > 0 && 0 === u && this.globalDone) {
             var duration = this.globalDone;
             this.globalDone = null,
             duration()
         }
     },
-    adjustSpeed: function(currentTime, startY) {
-        for (var wholeY = this.getById(currentTime), duration = 0; duration < wholeY.length; duration++) {
-            var r = wholeY[duration];
-            r.duration /= startY,
-            r.current /= startY
+    adjustSpeed: function(e, t) {
+        for (var u = this.getById(e), duration = 0; duration < u.length; duration++) {
+            var r = u[duration];
+            r.duration /= t,
+            r.current /= t
         }
     },
-    getById: function(currentTime) {
-        return this.funcs.filter(function(startY) {
-            return currentTime === startY.id
+    getById: function(e) {
+        return this.funcs.filter(function(t) {
+            return e === t.id
         })
     },
-    get: function(currentTime) {
-        for (var startY = 0; startY < this.funcs.length; startY += 1)
-            if (this.funcs[startY].func === currentTime)
-                return this.funcs[startY];
+    get: function(e) {
+        for (var t = 0; t < this.funcs.length; t += 1)
+            if (this.funcs[t].func === e)
+                return this.funcs[t];
         return null
     },
-    isRunning: function(currentTime) {
-        var startY = this.get(currentTime);
-        return null !== startY && startY.running
+    isRunning: function(e) {
+        var t = this.get(e);
+        return null !== t && t.running
     },
     countActive: function() {
-        for (var currentTime = 0, startY = 0; startY < this.funcs.length; startY += 1)
-            currentTime += this.funcs[startY].running;
-        return currentTime
+        for (var e = 0, t = 0; t < this.funcs.length; t += 1)
+            e += this.funcs[t].running;
+        return e
     },
     listActive: function() {
-        for (var currentTime = [], startY = 0; startY < this.funcs.length; startY += 1)
-            this.funcs[startY].running && currentTime.push(this.funcs[startY].name);
-        return currentTime
+        for (var e = [], t = 0; t < this.funcs.length; t += 1)
+            this.funcs[t].running && e.push(this.funcs[t].name);
+        return e
     },
-    done: function(currentTime) {
-        this.globalDone = currentTime
+    done: function(e) {
+        this.globalDone = e
     },
-    cancelById: function(currentTime, dealCancelFun) { //xzw add dealDone
-        var startY = void 0 === currentTime ? 0 : currentTime;
+    cancelById: function(e, dealCancelFun) { //xzw add dealDone
+        var t = void 0 === e ? 0 : e;
 		 
-        this.funcs = this.funcs.filter(function(currentTime) {
-			var is = currentTime.id == startY;
+        this.funcs = this.funcs.filter(function(e) {
+			var is = e.id == t;
 			
 			if(is && dealCancelFun){
-				currentTime.cancelFun && currentTime.cancelFun()
+				e.cancelFun && e.cancelFun()
 			} 
             return !is
         })
     },
-    cancel: function(currentTime) {
-        this.funcs = this.funcs.filter(function(startY) {
-            return startY.func !== currentTime
+    cancel: function(e) {
+        this.funcs = this.funcs.filter(function(t) {
+            return t.func !== e
         })
     },
     getUniqueId: function() {

+ 31 - 1
src/viewer/EDLRenderer.js

@@ -265,14 +265,44 @@ export class EDLRenderer{//Eye-Dome Lighting 眼罩照明
             if(Features.EXT_DEPTH.isSupported()){   
                 //借用rtEDL存储深度信息 
                 viewer.renderer.setRenderTarget(params.rtEDL || this.rtEDL);
+                 
+                //pointDensity已经使用的是panorama模式,在画面边缘点云会稀疏,遮挡效果差
                 
-                
+                /* if(Potree.settings.displayMode == "showPanos"){ //还原成点云模式的材质,且可能要更大些,因点云变稀疏
+                    var matBefore = { 
+                        pointSizeType : new Map(),
+                        size :  new Map(),    
+                        usePanoMap :  new Map(),
+                    } 
+                    for (let pointcloud of visiblePointClouds2) { 
+                        matBefore.usePanoMap.set(pointcloud, pointcloud.material.usePanoMap)
+                        //matBefore.pointSizeType.set(pointcloud, pointcloud.material.pointSizeType)  
+                        matBefore.size.set(pointcloud, pointcloud.temp.pointSize)  
+                        
+                        //pointcloud.material.pointSizeType = Potree.config.material.pointSizeType //不能修改这项,因为是define,会卡。
+                        //pointcloud.changePointSize(pointcloud.temp.pointSize * (1+Potree.config.material.sizeAddAtPanoRtEDL))
+                        
+                        //pointcloud.changePointSize(Potree.config.material.sizeAtPanoRtEDL, true)
+                        pointcloud.material.usePanoMap = false  //禁止使用absolutePanoramaSize大小
+                        
+                    }
+                }  */   
                 //渲染scenePointCloud到rtEDL
                 viewer.pRenderer.render(viewer.scene.scenePointCloud, camera, params.rtEDL || this.rtEDL, {
                     shadowMaps:  lights.length > 0 ? [this.shadowMap] : null,
                     clipSpheres: viewer.scene.volumes.filter(v => (v instanceof SphereVolume)),
                     transparent: false,
                 });
+                
+                
+                /* if(Potree.settings.displayMode == "showPanos"){ 
+                    for (let pointcloud of visiblePointClouds2) {
+                         
+                        //pointcloud.material.pointSizeType = matBefore.pointSizeType.get(pointcloud)
+                        pointcloud.material.usePanoMap = matBefore.usePanoMap.get(pointcloud)
+                        //pointcloud.changePointSize(matBefore.size.get(pointcloud))
+                    }
+                } */
             } 
 		}
         

+ 20 - 12
src/viewer/View.js

@@ -220,9 +220,14 @@ export class View extends THREE.EventDispatcher{
         // position, target, duration = 0, callback = null, onUpdate = null, Easing='', cancelFun
         transitions.cancelById(this.LookTransition, true ); 
         
-        let done = ()=>{
-            info.callback && info.callback()
-            endTarget && this.lookAt(endTarget); //compute radius for orbitcontrol
+        let done = ()=>{ 
+            if(endTarget){
+                this.lookAt(endTarget); //compute radius for orbitcontrol
+            }else if(endQuaternion){
+                this.rotation = new THREE.Euler().setFromQuaternion(endQuaternion)
+            }
+             
+            info.callback && info.callback() 
             this.dispatchEvent('setViewDone')
         }
         
@@ -230,15 +235,19 @@ export class View extends THREE.EventDispatcher{
 	 
         const startPosition = this.position.clone();
 		const startTarget = this.getPivot();
+        let startQuaternion = math.getQuaFromPosAim(startPosition,startTarget)
+        
+		let endTarget = null, endQuaternion ;
+        
+        
         
         
-		let endTarget = null, endQuaternion, startQuaternion;
 		if(info.target ){
-			endTarget = new THREE.Vector3().copy(info.target) 
-            
-            endQuaternion = math.getQuaFromPosAim(endPosition,endTarget)
-            startQuaternion = math.getQuaFromPosAim(startPosition,startTarget)
-		}
+			endTarget = new THREE.Vector3().copy(info.target)  
+            endQuaternion = math.getQuaFromPosAim(endPosition,endTarget) 
+		}else if(info.quaternion){
+            endQuaternion = info.quaternion.clone()
+        }
          
          
 		if(!info.duration){
@@ -252,8 +261,7 @@ export class View extends THREE.EventDispatcher{
             transitions.start(lerp.vector(this.position, endPosition, (pos, progress)=>{
 				let t = progress 
  
-                if(endQuaternion){ 
-                    
+                if(endQuaternion){  
                     let quaternion = (new THREE.Quaternion()).copy(startQuaternion) 
                     lerp.quaternion(quaternion, endQuaternion)(progress),
                     this.rotation = new THREE.Euler().setFromQuaternion(quaternion)
@@ -262,7 +270,7 @@ export class View extends THREE.EventDispatcher{
  
 
                 info.onUpdate && info.onUpdate(t)//add
-            }), info.duration, done, 0, info.Easing ? easing[info.Easing] : easing.easeInOutQuad,null, this.LookTransition, info.cancelFun); 
+            }), info.duration, done, 0, info.Easing ? easing[info.Easing] : easing.easeInOutSine /*easeInOutQuad */,null, this.LookTransition, info.cancelFun); 
 
 
         } 

+ 6 - 0
src/viewer/map/Map.js

@@ -107,6 +107,12 @@ export class MapLayer extends THREE.EventDispatcher{ // 包括了 MapLayerBase S
         return floorplan
     }
     
+    
+    getFloorplan(datasetId){
+        return this.maps.find(e=>e.name == 'floorplan'+"_"+ datasetId  )
+    }
+    
+    
     addMap(t){ 
         this.maps.push(t)
         //this.view.invalidateScene()

+ 482 - 12
src/viewer/viewer.js

@@ -2658,17 +2658,10 @@ export class Viewer extends ViewerBase{
     }
     
      
-    updateVisible(object, reason, ifShow, force){//当所有加入的条件都不为false时才显示. reason='force'一般是强制、临时的
+    /* updateVisible(object, reason, ifShow, force){//当所有加入的条件都不为false时才显示. reason='force'一般是强制、临时的
         if(!object.unvisibleReasons) object.unvisibleReasons = []; //如果length>0代表不可见
         if(!object.forceVisibleReasons) object.forceVisibleReasons = []; //只要有一项代表一定可见,优先级比unvisibleReasons高
-        
-        /* let mapChange = ()=>{//还是算了,有时候可见性的改变 在mapViewer和mainViewer中交替,如reticule,就会频繁
-            var layers = ['measure','map','mapObjects','bothMapAndScene'] 
-            if(layers.some(e=> object.layers && (object.layers.mask == Potree.config.renderLayers[e])  )) { 
-                this.mapViewer.dispatchEvent({type:'content_changed'})
-            }
-        } */
-             
+            
         if(ifShow){
             if(force){
                 object.forceVisibleReasons.includes(reason) || object.forceVisibleReasons.push(reason)
@@ -2726,12 +2719,83 @@ export class Viewer extends ViewerBase{
             }  
         }
         
+    } */ 
+     
+     
+    updateVisible(object, reason, ifShow, level=0, type){//当所有加入的条件都不为false时才显示. reason='force'一般是强制、临时的
+        if(!object.unvisibleReasons) object.unvisibleReasons = []; //如果length>0代表不可见
+        if(!object.visibleReasons) object.visibleReasons = []; //在同级时,优先可见
+        
+        
+        var update = function(){
+            
+            //先按从高到低的level排列
+            object.unvisibleReasons = object.unvisibleReasons.sort((a,b)=>b.level-a.level)
+            object.visibleReasons = object.visibleReasons.sort((a,b)=>b.level-a.level)
+            var maxVisiLevel = object.visibleReasons[0] ? object.visibleReasons[0].level : -1
+            var maxunVisiLevel = object.unvisibleReasons[0] ? object.unvisibleReasons[0].level : -1
+            
+            var shouldVisi = maxVisiLevel >= maxunVisiLevel
+            var visiBefore = object.visible
+            
+            
+            if(visiBefore != shouldVisi){
+                object.visible = shouldVisi
+                object.dispatchEvent({
+                    type: 'isVisible',
+                    visible: shouldVisi,
+                    reason,
+                }) 
+            }
+            
+            
+        }    
+        
+        
+        
+        if(ifShow){ 
+
+            var index = object.unvisibleReasons.findIndex(e=>e.reason == reason) 
+            if(index > -1){
+                type = 'cancel'
+                object.unvisibleReasons.splice(index, 1); 
+            }
+            
+            if(type == 'add' ){
+                if(!object.visibleReasons.some(e=>e.reason == reason)){
+                    object.visibleReasons.push({reason,level})
+                }
+            } 
+        }else{ 
+            var index = object.visibleReasons.findIndex(e=>e.reason == reason) 
+            if(index > -1){
+                type = 'cancel'
+                object.visibleReasons.splice(index, 1); 
+            }
+            
+            if(type != 'cancel' ){
+                if(!object.unvisibleReasons.some(e=>e.reason == reason)){
+                    object.unvisibleReasons.push({reason,level})
+                }
+            }
+        }
+        
+        
+        
+        update()
+        
+        
+        
+        
     } 
      
+     
+     
+     
     getObjVisiByReason(object,reason){//获取在某条件下是否可见.  注: 用户在数据集选择可不可见为"datasetSelection"
         if(object.visible)return true
         else{
-            return !object.unvisibleReasons || !object.unvisibleReasons.includes(reason)  
+            return !object.unvisibleReasons || !object.unvisibleReasons.some(e=>e.reason == reason)  
         }
     } 
      
@@ -3043,7 +3107,7 @@ export class Viewer extends ViewerBase{
                 this.images360.removeEventListener('cameraMoveDone',f)
             }
             this.images360.addEventListener('cameraMoveDone',f) 
-            return {promise: deferred.promise() }();  
+            return {promise: deferred.promise() }   
         }
         if (type == 'measure') {  
             target.copy(object.getCenter()) 
@@ -3556,7 +3620,20 @@ export class Viewer extends ViewerBase{
         viewer.inputHandler.toggleSelection(object);   
     }
     
-     
+    pointInWhichPointcloud(pos){//选择最接近中心的那个 使用boundSphere 
+        let result = Common.sortByScore(this.scene.pointclouds,[],[
+            (pointcloud)=>{ 
+                var size = pointcloud.pcoGeometry.tightBoundingBox.getSize(new THREE.Vector3)
+                var center = pointcloud.bound.getCenter(new THREE.Vector3)
+                var length = size.length()
+                var dis = pos.distanceTo(center);
+                return length / dis  //到数据集中心的距离占数据集大小越小越好
+            }
+        ])
+        //若要求更准确的话,可以使用ifContainsPoint判断一下是否在bound中
+        let r = result && result[0];
+        return r.score > 1 ? result[0].item : null  
+    }
     
     /* addObjectTest1(){//加水管
         
@@ -3756,9 +3833,402 @@ export class Viewer extends ViewerBase{
         
         
         
+    addVideo11(){
+        if(Potree.settings.number != 'SS-fckI7CClKC')return
+        
+        
+         
+        var video = $(`<video  controls="controls" loop autoplay x5-playsinline="" webkit-playsinline="true" playsinline="true" controlslist="nodownload"></video>`)[0]
+        video.setAttribute("crossOrigin", 'Anonymous') 
+        //video.src = Potree.resourcePath+'/video/SS-fckI7CClKC/19.mp4'
+                 
+        var map = new THREE.VideoTexture(video); 
+        var plane = this.videoPlane = new THREE.Mesh(new THREE.PlaneGeometry(1, 1, 1, 1), new THREE.MeshBasicMaterial({
+            color:"#ffffff", 
+            transparent: !0,
+            depthTest:false,
+            opacity:0.7,
+            side:2,            
+            map
+        }))
+        plane.visible = false
+        
+        plane.geometry.computeBoundingBox();
+        plane.boundingBox = plane.geometry.boundingBox.clone()//.applyMatrix4()
+        plane.boundingBox.max.z = 1
+        plane.boundingBox.max.y = -0.4
+        plane.boundingBox.max.x = 1 
+        
+        /* plane.position.copy(this.images360.panos[19].position);
+        plane.lookAt(plane.position.clone().setX(0))
+        
+ 
+        
+        
+        9:
+        viewer.videoPlane.rotation.set(-1.432978005954197, 1.2296264545169697, 3.0098547630197667)
+        viewer.videoPlane.position.set( 6.532456676287381, -9.806373049095631,  -0.024205281024294284) 
+        //viewer.transformObject(viewer.videoPlane)
+        
+        //19:
+        viewer.videoPlane.rotation.set( 1.627167773445286, -1.172425902600188, 0.04682299709711613)
+        viewer.videoPlane.position.set( -9.558613948539932,-1.042301166581578,  0.08159683876743667)  */
+ 
+ 
+        
+        video.addEventListener('loadeddata', function(e) {
+             video.play()
+             //plane.scale.set(video.videoWidth/1000,video.videoHeight/1000,1)  // 1080 * 1920
+             console.log('video loadeddata')
+        }) 
+        
+        plane.scale.set(1080/1000,1920/1000,1)  // 1080 * 1920
+        
+        
+        
+        var startPlay = ()=>{
+            video.play() 
+            //video.pause()
+            //video.currentTime = 0.1;
+            this.removeEventListener('global_mousedown', startPlay)
+        }
+        
+        this.addEventListener('global_mousedown', startPlay)
+        
+        
+        var videoInfo = {
+            9:{
+                rotation:[-1.432978005954197, 1.2296264545169697, 3.0098547630197667],
+                position:[6.532456676287381, -9.806373049095631,  -0.024205281024294284]
+            },
+            19:{
+                rotation:[1.627167773445286, -1.172425902600188, 0.04682299709711613],
+                position:[-9.558613948539932,-1.042301166581578,  0.08159683876743667]
+            },
+             
+        }
     
+        /* this.images360.addEventListener('cameraMoveDone',(e)=>{
+            let info = videoInfo[this.images360.currentPano.id]
+            if(info ){
+                plane.visible = true; 
+                plane.material.opacity = 1;
+                plane.position.fromArray(info.position)  
+                plane.rotation.fromArray(info.rotation)  
+            }
+            
+            
+        })  */
+        
+        
+        this.images360.addEventListener('flyToPano' ,(e)=>{//飞之前
+            if(Potree.settings.displayMode != 'showPanos') return
+            let info = videoInfo[e.toPano.pano.id]
+            if(info ){ //出现 
+                setTimeout(()=>{
+                    plane.visible = true;  
+                    plane.position.fromArray(info.position)  
+                    plane.rotation.fromArray(info.rotation)
+                            
+                    video.src = Potree.resourcePath+`/video/${Potree.settings.number}/${e.toPano.pano.id}.mp4`
+                    video.play();
+                    video.currentTime = 0
+                    Potree.settings.zoom.enabled = false
+                    
+                    transitions.start(lerp.property(plane.material, "opacity", 1/* , (e)=>{console.log('fadeIn',e)} */) , e.toPano.duration*0.4 , ()=>{
+              
+                    }, 0,   easing['easeInOutQuad'])  
+                },  e.toPano.duration*0.6)  //时间上不能和消失的重叠 延迟
+                
+                
+            }
+            
+            //消失
+            transitions.start(lerp.property(plane.material, "opacity", 0, /* (e)=>{console.log('fadeOut',e)} */) , e.toPano.duration*0.4, ()=>{
+                if(!info){
+                    plane.visible = false
+                    video.pause()
+                    Potree.settings.zoom.enabled = true 
+                }
+            }, 0,   easing['easeInOutQuad'])
+            
+            
+        })
+        
+        
+        
+        this.images360.addEventListener('endChangeMode',(e)=>{  //暂时不处理初始加载时就在有视频的点位上的情况
+            if(e.mode == 'showPanos'){ 
+                let info = videoInfo[this.images360.currentPano.id]
+                if(info ){ //出现  
+                    plane.visible = true;  
+                    plane.position.fromArray(info.position)  
+                    plane.rotation.fromArray(info.rotation)
+                    plane.material.opacity = 0   
+                    
+                    video.src = Potree.resourcePath+`/video/${Potree.settings.number}/${this.images360.currentPano.id}.mp4`
+                    video.play();
+                    video.currentTime = 0
+                    Potree.settings.zoom.enabled = false
+                    
+                    transitions.start(lerp.property(plane.material, "opacity", 1, (e)=>{console.log('fadeIn',e)}) , 300 , ()=>{
+              
+                    }, 0,   easing['easeInOutQuad'])   
+                    
+                }  
+            }else{
+                plane.visible = false; 
+                Potree.settings.zoom.enabled = true
+            }
+            
+        })
+        
+        this.scene.scene.add(plane)
+    }
+    ////////////////////////
     
+    addVideo(){
+        if(Potree.settings.number != 'SS-t-P6zBR73Gke')return
+        var geo = new THREE.PlaneGeometry(1, 1, 1, 1)
+        
+        var videoInfo = this.videoInfo = [
+            /* {
+                id: 45, 
+                url: 'https://laser-oss.4dkankan.com/testdata/SS-t-P6zBR73Gke/temp/poi/2022/05/09/c02a2c1e-8420-4f34-b951-5f7a07abe932.mp4',
+                rotation:[-1.629007730553656,   0.042029565584517974, -3.1345506775116627],
+                position:[ 9.467649296794061,  -0.7596961214872837,  -0.12477576310191862],
+                scale:[4.52209111454416,3.3888400031207984,1],
+ 
+            }, */ 
+
+            {
+                id: '40-2', 
+                url: 'https://laser-oss.4dkankan.com/testdata/SS-t-P6zBR73Gke/temp/poi/2022/05/10/0aabafee-36b8-455d-9c11-0780bf694786.mp4',
+                rotation:[-1.494468618954883,   -1.4987317433158989,  -3.061254983446741],
+                position:[ 19.801820617361624,  2.884673619844108,   -0.03362305858221648],
+                scale:[3.5741423153151763,  2.8738725275578703, 1], 
+            },
+
+            
+            { 
+                id: 40,
+                /* rotation:[-1.534692822378723, 0.01083403560862361,  3.141535283661569],
+                position:[17.2934294239949861, 2.413510747928117, -0.008057029580231356], */
+                url: 'https://laser-oss.4dkankan.com/testdata/SS-t-P6zBR73Gke/temp/poi/2022/05/09/7896d6ef-a2d6-4fd7-949c-768782a5b484.mp4',
+             
+                rotation:[-1.5487684197910518,   0.021848470169552752, -3.1387534893955236],
+                position:[17.277316608096, 2.0840432922115846,  -0.0931149415437065],
+                scale:[2.0821757723834047, 0.6129478480765236, 1], 
+                visibles: [40]
+            },
+             
+        ]
+        let add = (info)=>{
+            var video = $(`<video  controls="controls" loop autoplay x5-playsinline="" webkit-playsinline="true" playsinline="true" controlslist="nodownload"></video>`)[0]
+            video.setAttribute("crossOrigin", 'Anonymous') 
+            video.src = info.url || Potree.resourcePath+`/video/${Potree.settings.number}/${info.id}.mp4`
+            
+            var map = new THREE.VideoTexture(video); 
+            var plane = this.videoPlane = new THREE.Mesh(geo, new THREE.MeshBasicMaterial({
+                color:"#ffffff", 
+                transparent: !0,
+                depthTest:false,
+                opacity:0 ,
+                //side:2,            
+                map
+            }))
+            plane.position.fromArray(info.position)  
+            plane.rotation.fromArray(info.rotation) 
+            info.scale && plane.scale.fromArray(info.scale) 
+            this.scene.scene.add(plane)
+            info.plane = plane
+            plane.boundingBox = new THREE.Box3(new THREE.Vector3(0,-0.5,0),new THREE.Vector3(1,-0.4,0.2))
+            video.addEventListener('loadeddata', function(e) {
+                 video.play()
+                 if(!info.visibles/* ||!viewer.images360.currentPano || info.visibles.includes(viewer.images360.currentPano.id) */){
+                     plane.material.opacity = 1
+                 } 
+                    
+                 info.scale || plane.scale.set(video.videoWidth/1000,video.videoHeight/1000,1)  // 1080 * 1920
+                 console.log('video loadeddata', info.id)
+            }) 
+            
+            
+            
+            if(info.visibles){
+                this.images360.addEventListener('flyToPano' ,(e)=>{//飞之前 
+                    if(info.visibles.includes(e.toPano.pano.id)){ //出现 
+                        setTimeout(()=>{
+                            plane.visible = true; 
+                                    
+                            video.play();
+                            video.currentTime = 0
+                            Potree.settings.zoom.enabled = false
+                            
+                            transitions.start(lerp.property(plane.material, "opacity", 1 ) , e.toPano.duration*0.4 , ()=>{
+                      
+                            }, 0,   easing['easeInOutQuad'])  
+                        },  e.toPano.duration*0.6)  //时间上不能和消失的重叠 延迟 
+                        
+                    }else{
+                        //消失
+                        transitions.start(lerp.property(plane.material, "opacity", 0,  ) , e.toPano.duration*0.4, ()=>{
+                            if(!info){
+                                plane.visible = false
+                                video.pause()
+                                Potree.settings.zoom.enabled = true 
+                            }
+                        }, 0,   easing['easeInOutQuad'])
+                    } 
+                    
+                })
+            }
+                
+            
+            
+            var startPlay = ()=>{
+                video.play() 
+                //video.pause()
+                //video.currentTime = 0.1;
+                this.removeEventListener('global_mousedown', startPlay)
+            }
+            
+            this.addEventListener('global_mousedown', startPlay)
+            Potree.settings.isTest && plane.addEventListener('select',(e)=>{console.log(e)})
+        }
+        
+
+        videoInfo.forEach(info=>{
+            add(info) 
+        }) 
+
+        
+        /* var video = $(`<video  controls="controls" loop autoplay x5-playsinline="" webkit-playsinline="true" playsinline="true" controlslist="nodownload"></video>`)[0]
+        video.setAttribute("crossOrigin", 'Anonymous') 
+        video.src = Potree.resourcePath+'/video/SS-t-P6zBR73Gke/40.mp4'
+                 
+        var map = new THREE.VideoTexture(video); 
+        var plane = this.videoPlane = new THREE.Mesh(geo, new THREE.MeshBasicMaterial({
+            color:"#ffffff", 
+            transparent: !0,
+            depthTest:false,
+            opacity:0.7,
+            side:2,            
+            map
+        }))
+        //plane.visible = false
+        this.scene.scene.add(plane)
+        plane.geometry.computeBoundingBox();
+        plane.boundingBox = plane.geometry.boundingBox.clone()//.applyMatrix4()
+        plane.boundingBox.max.z = 0.3
+        plane.boundingBox.max.y = -0.4
+        plane.boundingBox.max.x = 1 
+        
+        
+        
+        plane.position.copy(this.images360.panos[40].position);
+        plane.lookAt(plane.position.clone().setX(0))
+        
+ 
+        plane.rotation.set(-1.534692822378723, 0.01083403560862361,  3.141535283661569)
+        plane.position.set(  17.2934294239949861, 2.413510747928117, -0.008057029580231356)   
+          
     
+         
+        //viewer.transformObject(viewer.videoPlane)
+        
+        //19:
+         
+ 
+ 
+        
+        video.addEventListener('loadeddata', function(e) {
+             video.play()
+             plane.scale.set(video.videoWidth/1000,video.videoHeight/1000,1)  // 1080 * 1920
+             console.log('video loadeddata')
+        }) 
+        
+        //plane.scale.set(1080/1000,1920/1000,1)  // 1080 * 1920
+        
+        
+        
+        var startPlay = ()=>{
+            video.play() 
+            //video.pause()
+            //video.currentTime = 0.1;
+            this.removeEventListener('global_mousedown', startPlay)
+        }
+        
+        this.addEventListener('global_mousedown', startPlay)
+        
+        */
+        
+     
+        
+        /* this.images360.addEventListener('flyToPano' ,(e)=>{//飞之前
+            if(Potree.settings.displayMode != 'showPanos') return
+            let info = videoInfo[e.toPano.pano.id]
+            if(info ){ //出现 
+                setTimeout(()=>{
+                    plane.visible = true;  
+                    plane.position.fromArray(info.position)  
+                    plane.rotation.fromArray(info.rotation)
+                            
+                    video.src = Potree.resourcePath+`/video/${Potree.settings.number}/${e.toPano.pano.id}.mp4`
+                    video.play();
+                    video.currentTime = 0
+                    Potree.settings.zoom.enabled = false
+                    
+                    transitions.start(lerp.property(plane.material, "opacity", 1 ) , e.toPano.duration*0.4 , ()=>{
+              
+                    }, 0,   easing['easeInOutQuad'])  
+                },  e.toPano.duration*0.6)  //时间上不能和消失的重叠 延迟
+                
+                
+            }
+            
+            //消失
+            transitions.start(lerp.property(plane.material, "opacity", 0,  ) , e.toPano.duration*0.4, ()=>{
+                if(!info){
+                    plane.visible = false
+                    video.pause()
+                    Potree.settings.zoom.enabled = true 
+                }
+            }, 0,   easing['easeInOutQuad'])
+            
+            
+        })
+        
+        
+        
+        this.images360.addEventListener('endChangeMode',(e)=>{  //暂时不处理初始加载时就在有视频的点位上的情况
+            if(e.mode == 'showPanos'){ 
+                let info = videoInfo[this.images360.currentPano.id]
+                if(info ){ //出现  
+                    plane.visible = true;  
+                    plane.position.fromArray(info.position)  
+                    plane.rotation.fromArray(info.rotation)
+                    plane.material.opacity = 0   
+                    
+                    video.src = Potree.resourcePath+`/video/${Potree.settings.number}/${this.images360.currentPano.id}.mp4`
+                    video.play();
+                    video.currentTime = 0
+                    Potree.settings.zoom.enabled = false
+                    
+                    transitions.start(lerp.property(plane.material, "opacity", 1, (e)=>{console.log('fadeIn',e)}) , 300 , ()=>{
+              
+                    }, 0,   easing['easeInOutQuad'])   
+                    
+                }  
+            }else{
+                plane.visible = false; 
+                Potree.settings.zoom.enabled = true
+            }
+            
+        })
+         
+        */
+    }
     
     
     

+ 56 - 0
改bug的历史.txt

@@ -4,7 +4,60 @@
 
 
 
+2022-04-24 
+ios 15.4.1 渲染问题,好像clear有时失效
+	 相机离远后就留下了没clear的画面   
+	 全景图显示不出
+	viewer.dispatchEvent({type: "render.begin",  viewer: viewer, viewport:view, params })这句 删除后改善很多, 或者sprite 的applyMatrix不执行(如果执行,在不改变位移时也正常)	
+	但同时也要删除  if(width == 0 || height == 0)return  但只要在this.renderer.render(this.scene.scene, camera);  之后return也可
+	  
+	在loop中	延迟渲染也一样有问题  
+
+	只渲染overlay且不clear时,电脑是不clear的状态但是这个手机竟然自动clear了,全景图也能显示出,而且没有执行renderer.clear,也无gl.clear。执行renderer.clear反而有残影
+	但clearcolor确实没有生效 
+	地图正常(使gl.clear非正常执行 ) 
+ 
+	用地图的renderer在地图渲染三维的场景clear也正常 
+	是不是有类似setSize的函数可以起到clear的作用? 没找到
+
+
+	发现测量线最能引起这个bug,然后就发现navvis测量也这样了。
+  	但具体哪一句造成一开始加载就
+
+
+	专注一下后续系统或者navvis是否解决。暂时屏蔽了EXT_frag_depth
+
+ 
+
+
+2022-04-18
+
+4dkk上传下载页面 上传全景图后首次刷新会有黑块 (只在上传下载页面才会) 
+  (!i || i && i === r.tile.panoId) && r.level 这个报错,原因未知,修改了一下,不报错但还是会黑块 
+同时出现automation没有init,原因是图没加载好,所以startInside没有成功回调 
+ 需要关闭浏览器的禁止缓存,否则bug出现不了
+
+虽然不知道为什么图加载顺序和通常的不一样了,但终结原因是图加载的问题,故而修改了下uploadTile,增加LodDescripor.uploaded,可控性更强;但希望ignore不会造成有一部分模糊这种情况
+ 
+ 
+
+ 
+
+
 
+2022-04-15
+该双数据集场景全景模式拖拽画面时扭曲抖动特别厉害,猜测是因为boundingbox非常大导致skybox非常大? 
+ viewer.images360.cube.scale : 22692.381042028544, y: 1525345.1015381122, z: 7.563655000000001, 
+xyz改为一样 ,后不抖动了, 但是旋转时会有黑影闪现。 
+far增大, 黑影消失, 但是能看到贴图水平或垂直有一条白线 
+把位置放到相机的位置后 就正常了!
+
+综上猜测是精度问题?所以最好是居中于相机的正方体?可过渡怎么办 
+http://localhost:8080/index.html?m=t-OdiKZBDVL0#/data
+
+但是这样bump时几乎没有移动,左右bump不可能用fov 
+
+结论:修改了updateCube函数
 
 
 2022-03-23
@@ -17,6 +70,7 @@
 ·如果没有hover到别的viewport就正常
 ·会不会是nodes的切换问题
 ·加了这句就行了Potree.updatePointClouds
+·3.31发现bug又出现了了, 是因为修改了四个屏幕的点云质量,要在pick前执行一下beforeRender
 
 
 子问题:为什么pick截图保存到的是一整张图?而我自己改成pickState.renderTarget.scissor 这种绘制的就不会,但是清除也只清除当前区域了。
@@ -77,6 +131,8 @@ tiledownloader下载完成会触发tiledownloader开始uploadTile.
 
 
 
+ 
+
 
 --更早前: