xzw %!s(int64=2) %!d(string=hai) anos
pai
achega
8a629d09e5
Modificáronse 59 ficheiros con 2136 adicións e 2615 borrados
  1. 1 1
      examples/4dkk.html
  2. 1 1
      gulpfile.js
  3. 63 74
      libs/three.js/3dtiles/three-loader-3dtiles.esm.js
  4. 10 10
      libs/three.js/lines/LineMaterial.js
  5. 1 1
      libs/three.js/loaders/GLTFLoader.js
  6. 15 13
      src/ExtendPointCloudOctree.js
  7. 7 5
      src/custom/materials/DepthBasicMaterial.js
  8. 4 4
      src/custom/materials/ModelTextureMaterial.js
  9. 2 2
      src/custom/materials/postprocessing/OutlinePass.js
  10. 3 3
      src/custom/mergeStartTest.js
  11. 3 3
      src/custom/modules/CameraAnimation/CameraAnimation.js
  12. 6 6
      src/custom/modules/clipModel/Clip.js
  13. 6 6
      src/custom/modules/clipping/Clipping.js
  14. 4 4
      src/custom/modules/datasetAlignment/Alignment.js
  15. 4 4
      src/custom/modules/mergeModel/MergeEditor.js
  16. 128 52
      src/custom/modules/panoEdit/panoEditor.js
  17. 8 4
      src/custom/modules/panos/DepthImageSampler.js
  18. 501 1171
      src/custom/modules/panos/Images360.js
  19. 34 87
      src/custom/modules/panos/Panorama.js
  20. 12 10
      src/custom/modules/panos/tile/PanoRenderer.js
  21. 6 6
      src/custom/modules/panos/tile/TileDownloader.js
  22. 22 26
      src/custom/modules/route/RouteGuider.js
  23. 19 22
      src/custom/modules/siteModel/BuildingBox.js
  24. 36 14
      src/custom/modules/siteModel/SiteModel.js
  25. 29 24
      src/custom/objects/Magnifier.js
  26. 20 14
      src/custom/objects/Reticule.js
  27. 3 3
      src/custom/objects/fireParticle/explode/ExplodeParticle.js
  28. 3 3
      src/custom/objects/fireParticle/fire/FireParticle.js
  29. 3 3
      src/custom/objects/fireParticle/smoke/SmokeParticle.js
  30. 1 1
      src/custom/objects/tool/CurveCtrl.js
  31. 5 5
      src/custom/objects/tool/Measure.js
  32. 1 1
      src/custom/objects/tool/MeasuringTool.js
  33. 17 13
      src/custom/objects/tool/TransformControls.js
  34. 1 1
      src/custom/objects/tool/mapClipBox.js
  35. 222 26
      src/custom/potree.shim.js
  36. 26 39
      src/custom/settings.js
  37. 54 8
      src/custom/start.js
  38. 1 1
      src/custom/three.shim.js
  39. 0 20
      src/custom/utils/Common.js
  40. 14 2
      src/custom/utils/DrawUtil.js
  41. 11 16
      src/custom/utils/SplitScreen4Views.js
  42. 224 576
      src/custom/viewer/ViewerNew.js
  43. 4 2
      src/custom/viewer/Viewport.js
  44. 241 157
      src/custom/viewer/map/Map.js
  45. 152 63
      src/custom/viewer/map/MapViewer.js
  46. 9 7
      src/custom/viewer/viewerBase.js
  47. 3 2
      src/loader/BinaryLoader.js
  48. 7 7
      src/materials/shaders/depthBasic.fs
  49. 22 1
      src/materials/shaders/otherShaders.js
  50. 17 5
      src/navigation/InputHandlerNew.js
  51. 11 10
      src/utils/TransformationToolNew.js
  52. 1 1
      src/utils/VolumeNew.js
  53. 72 60
      src/viewer/EDLRendererNew.js
  54. 4 4
      src/viewer/ExtendScene.js
  55. 2 2
      src/viewer/ExtendView.js
  56. 2 2
      src/viewer/PropertyPanels/PropertiesPanel.js
  57. 4 0
      src/viewer/Scene.js
  58. 1 1
      src/viewer/potree.css
  59. 53 6
      改bug的历史.txt

+ 1 - 1
examples/4dkk.html

@@ -30,7 +30,7 @@
 	<script src="../../build/potree/potree.js"></script>
 	<script src="../../libs/plasio/js/laslaz.js"></script>
 	
-	
+	<script src="../../libs/stats.js/stats.js"></script>
 	<div class="potree_container" style="position: absolute; width: 100%; height: 100%; left: 0px; top: 0px; ">
 		<div id="potree_render_area" style="background-image: url('../../build/potree/resources/images/background.jpg');">
             

+ 1 - 1
gulpfile.js

@@ -92,7 +92,7 @@ gulp.task('webserver', gulp.series(async function() {
 	server = connect.server({
 		port: 1234,
         host:'192.168.0.113',
-		https: true,
+		https: false,
 	});
 }));
 

+ 63 - 74
libs/three.js/3dtiles/three-loader-3dtiles.esm.js

@@ -6,6 +6,7 @@ import { KTX2Loader } from '../loaders/KTX2Loader.js';
 
 import MeshBasicMaterial  from '../../../src/custom/materials/BasicMaterial.js'  // xzw改  原先MeshBasicMaterial贴图发黑,可能和贴图有关
 
+let globalThis = window //add 有的app没有globalThis. 2023.1
 /*! *****************************************************************************
 Copyright (c) Microsoft Corporation.
 
@@ -15897,12 +15898,12 @@ async function loadImage(gltf, image, index, options, context) {
   }
 
   assert$1(arrayBuffer, 'glTF image has no data');
-  let parsedImage = await parse(arrayBuffer, [ImageLoader, BasisLoader], {
+   let parsedImage = await parse(arrayBuffer, [ImageLoader, BasisLoader], {
     mimeType: image.mimeType,
     basis: options.basis || {
       format: selectSupportedBasisFormat()
     }
-  }, context);
+  }, context); 
 
   if (parsedImage && parsedImage[0]) {
     parsedImage = {
@@ -17666,29 +17667,9 @@ class Loader3DTiles {
                         if (dracoLoader) {
                             dracoLoader.dispose();
                         }
-                    },
-                                                                                      
-                                            
-                                                        
-                                            
-                                                                                           
-                      
-                },
-                                                      
-                                                          
-                                    
-                                              
-                                                                                             
-                       
-                      
-                                                     
-                                             
-                                             
-                                            
-                                                                                           
-                      
-                  
-              
+                    },   
+                },                                                                             
+                    
             };
         });
     }
@@ -17704,60 +17685,68 @@ function createGLTFNodes(gltfLoader, tile, unlitMaterial, options, rootTransform
             if (shouldRotate) {
                 contentTransform.multiply(rotateX); // convert from GLTF Y-up to Z-up
             }
-            gltfLoader.parse(tile.content.gltfArrayBuffer, tile.contentUrl ? tile.contentUrl.substr(0, tile.contentUrl.lastIndexOf('/') + 1) : '', (gltf) => {
-                const tileContent = gltf.scenes[0];
-                tileContent.applyMatrix4(contentTransform);
-                
-                 
-                // !zeg改
-                //未知                                                                                                                                 
-                //tileContent.position.set(tile.header.boundingVolume.box[0], tile.header.boundingVolume.box[1], tile.header.boundingVolume.box[2])//add
-                //这个链接需要加上这句https://testgis.4dage.com/LVBADUI_qp/tileset.json //这和子集是否为json无关,为何在另一个工程正常
-                //console.log('位移tile', tileContent.position)  
-                
-                
-                
-                tileContent.traverse((object) => {
-                    if (object.type == "Mesh") {
-                        const mesh = object;
-                        //mesh.tileId = tile.id//add
-                        const originalMaterial = mesh.material;
-                        const originalMap = originalMaterial.map;
-                        if (options.material) {
-                            mesh.material = options.material.clone();
-                            originalMaterial.dispose();
-                        }
-                        else if (options.shading == Shading.FlatTexture) {
-                            mesh.material = unlitMaterial.clone();
-                            originalMaterial.dispose();
-                        }
-                        if (options.shading != Shading.ShadedNoTexture) {
-                            if (mesh.material.type == "ShaderMaterial") {
-                                mesh.material.uniforms.map = { value: originalMap };
+            gltfLoader.parse(
+                tile.content.type == 'glTF' ? tile.content.gltf.gltfArrayBuffer : tile.content.gltfArrayBuffer,//tile.content.gltfArrayBuffer,
+                tile.contentUrl ? tile.contentUrl.substr(0, tile.contentUrl.lastIndexOf('/') + 1) : '', 
+                (gltf) => {
+                    const tileContent = gltf.scenes[0];
+                    //tileContent.applyMatrix4(contentTransform);
+                     
+                    tileContent.traverse((object) => {
+                        if (object.type == "Mesh") {
+                            const mesh = object;
+                            //mesh.tileId = tile.id//add
+                            const originalMaterial = mesh.material;
+                            const originalMap = originalMaterial.map;
+                            if (options.material) {
+                                mesh.material = options.material.clone();
+                                originalMaterial.dispose();
+                            }
+                            else if (options.shading == Shading.FlatTexture) {
+                                mesh.material = unlitMaterial.clone();
+                                originalMaterial.dispose();
+                            }
+                            if (options.shading != Shading.ShadedNoTexture) {
+                                if (mesh.material.type == "ShaderMaterial") {
+                                    mesh.material.uniforms.map = { value: originalMap };
+                                }
+                                else {
+                                    mesh.material.map = originalMap;
+                                }
                             }
                             else {
-                                mesh.material.map = originalMap;
+                                if (originalMap) {
+                                    originalMap.dispose();
+                                }
+                                mesh.material.map = null;
                             }
-                        }
-                        else {
-                            if (originalMap) {
-                                originalMap.dispose();
+                            if (options.shaderCallback) {
+                                mesh.onBeforeRender = options.shaderCallback;
                             }
-                            mesh.material.map = null;
-                        }
-                        if (options.shaderCallback) {
-                            mesh.onBeforeRender = options.shaderCallback;
-                        }
-                        mesh.material.wireframe = options.wireframe;
-                        if (options.computeNormals) {
-                            mesh.geometry.computeVertexNormals();
+                            mesh.material.wireframe = options.wireframe;
+                            if (options.computeNormals) {
+                                mesh.geometry.computeVertexNormals();
+                            } 
+                            
+                            //------------------add on 2023.1.16----zeg
+                            
+                            mesh.geometry.applyMatrix4(contentTransform)
+                            if (tile.content.rtcCenter) {
+                                // 有些b3dm模型会将坐标写在源码的rtcCenter里 如https://testgis.4dage.com/LVBADUI_qp/tileset.json 
+                                mesh.geometry.translate(tile.content.rtcCenter[0], tile.content.rtcCenter[1], tile.content.rtcCenter[2])
+                            } else {
+                                mesh.geometry.scale(1, 1, -1) // 调整缩放,对应box也要进行变换(scaleZ对应box[2])
+                            }
+                            //---------------------
+                             
                         }
-                    }
-                });
-                resolve(tileContent);
-            }, (e) => {
-                reject(new Error(`error parsing gltf in tile ${tile.id}: ${e}`));
-            });
+                    });
+                    resolve(tileContent);
+                }, 
+                (e) => {
+                    reject(new Error(`error parsing gltf in tile ${tile.id}: ${e}`));
+                }
+            );
         });
     });
 }

+ 10 - 10
libs/three.js/lines/LineMaterial.js

@@ -46,7 +46,7 @@ UniformsLib.line = {
     clipDistance :          { type: 'f', 	value:  4}, //消失距离
     occlusionDistance :     { type: 'f', 	value:  1 }, //变为backColor距离
     maxClipFactor :         { type: 'f', 	value:  1 },  //0-1
-    
+    maxOcclusionFactor :    { type: 'f', 	value:  1 },  //0-1 
     
     
     depthTexture:{ value: null },
@@ -301,19 +301,14 @@ ShaderLib[ 'line' ] = {
 		uniform vec3 diffuse;
 		uniform float opacity;
 		uniform float lineWidth;
-        uniform vec3 backColor;
-        uniform float occlusionDistance;
-        uniform float clipDistance;
-        uniform float maxClipFactor;
+         
 		#ifdef USE_DASH
 
 			uniform float dashOffset;
 			uniform float dashSize;
-			uniform float gapSize;
-
+			uniform float gapSize; 
 		#endif
-
-
+ 
         //加
         #if defined(GL_EXT_frag_depth) && defined(useDepth)    
             uniform sampler2D depthTexture;
@@ -321,6 +316,11 @@ ShaderLib[ 'line' ] = {
             uniform float farPlane; 
             uniform vec2 resolution;
             uniform vec2 viewportOffset;
+            uniform vec3 backColor;
+            uniform float occlusionDistance;
+            uniform float clipDistance;
+            uniform float maxClipFactor;
+            uniform float maxOcclusionFactor;
         #endif
 
 
@@ -504,7 +504,7 @@ ShaderLib[ 'line' ] = {
                 if (delta > 0.0)
                 {
                     
-                    mixFactor = clamp(delta / occlusionDistance, 0.0, 1.0);
+                    mixFactor = clamp(delta / occlusionDistance, 0.0, maxOcclusionFactor);
                     clipFactor = clamp(delta / clipDistance, 0.0, maxClipFactor);
                 }
                  

+ 1 - 1
libs/three.js/loaders/GLTFLoader.js

@@ -3322,7 +3322,7 @@ class GLTFParser {
                 parser.textureLoader.load(sourceURI, (tex)=>{
                     tex.minFilter = THREE.LinearMipmapLinearFilter //原本:NearestMipMapNearestFilter 闪烁
                     
-                    Common.makeTexDontResize(tex) 
+                    Potree.Utils.makeTexDontResize(tex) 
                     //console.log(tex.image.width, tex.image.height)
                        
                     resolve(tex) 

+ 15 - 13
src/ExtendPointCloudOctree.js

@@ -115,6 +115,7 @@ export class ExtendPointCloudOctree extends PointCloudOctree{
         
         
         this.testMaxNodeCount ++
+        viewer.testMaxNodeCount ++
         if(this.testMaxNodeCount > 500){
             console.log('testMaxNodeLevel次数超出,强制结束:',this.dataset_id,  this.nodeMaxLevel,  this.nodeMaxLevelPredict.min) 
             this.testMaxNodeLevelDone = 'moreThanMaxCount'
@@ -162,6 +163,7 @@ export class ExtendPointCloudOctree extends PointCloudOctree{
             } 
             this.changePointOpacity()
         //}   
+        viewer.dispatchEvent('content_changed')  
     }
     
     //预测可能的nodeMaxLevel:
@@ -203,8 +205,8 @@ export class ExtendPointCloudOctree extends PointCloudOctree{
 		let getVal = (a, b) => a != void 0 ? a : b;
         
         
-        let pickWindowSize_ = THREE.Math.clamp( Math.round((1.1-this.maxLevel/this.nodeMaxLevel)*80),  5, 100)
-        
+        //let pickWindowSize_ = THREE.Math.clamp( Math.round((1.1-this.maxLevel/this.nodeMaxLevel)*80),  5, 100)
+        let pickWindowSize_ = THREE.Math.clamp( Math.round((1.1-this.maxLevel/this.nodeMaxLevel)*50),  3, 100)
 		let pickWindowSize = getVal(params.pickWindowSize, pickWindowSize_    ); /* 65 */ //拾取像素边长,越小越精准,但点云稀疏的话可能容易出现识别不到的情况。 另外左下侧会有缝隙无法识别到,缝隙大小和这个值有关
  
 		let pickOutsideClipRegion = getVal(params.pickOutsideClipRegion, false);
@@ -496,24 +498,21 @@ export class ExtendPointCloudOctree extends PointCloudOctree{
             
         }
         num /= (Potree.config.material.realPointSize / Potree.config.material.pointSize) //兼容 
-         
-        
-        
-        
+           
         num = Math.pow(num, 1.05) * 6 
+         
         
-        
-        
-        
+        let nodeMaxLevel = viewer.testMaxNodeCount > Potree.config.testNodeCount1 ? this.nodeMaxLevel : this.nodeMaxLevelPredict.max //防止刚开始因nodeMaxLevel没涨完,导致过大的点云突然出现
+         
         if(sizeFitToLevel || Potree.settings.sizeFitToLevel){//按照点云质量来调整的版本:    近似将pointSizeType换成ADAPTIVE
-            let str = this.temp.pointSize+':'+this.maxLevel+':'+this.nodeMaxLevel
+            let str = this.temp.pointSize+':'+this.maxLevel+':'+ nodeMaxLevel
             let value = this.temp.sizeFitToLevel[str]  //储存。防止每次渲染(反复切换density)都要算。
             if(value){
                 this.material.size = value
             }else{
                 
                 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.4)) : 0.1 //低质量的缩小点,因为视觉上看太大了。navvis是不铺满的,我们也留一点缝隙(但是ortho是不用缩小的,如果能分开判断就好了)
+                base *=  nodeMaxLevel > 0 ? Math.max(0.1, Math.pow(this.maxLevel /  nodeMaxLevel, 1.4)) : 0.1 //低质量的缩小点,因为视觉上看太大了。navvis是不铺满的,我们也留一点缝隙(但是ortho是不用缩小的,如果能分开判断就好了)
 
                 this.material.size = base * 5 * num/*  * window.devicePixelRatio */
                 //在t-8BCqxQAr93 会议室 和 t-e2Kb2iU 隧道 两个场景里调节,因为它们的spacing相差较大,观察会议室墙壁的龟裂程度
@@ -521,14 +520,16 @@ export class ExtendPointCloudOctree extends PointCloudOctree{
             }
         }else{ 
         
-            let base = 0.007;  //let base = this.material.spacing / Math.pow(2, this.nodeMaxLevel) //点云大小在level为0时设置为spacing,每长一级,大小就除以2
+            /* let base = 0.007; */ let base = this.material.spacing / Math.pow(2,  nodeMaxLevel) //点云大小在level为0时设置为spacing,每长一级,大小就除以2
             //base的数值理论上应该是右侧算出来的,但发现有的场景nodeMaxLevel和nodeMaxLevelPredict差别较大的点云显示也过大,而直接换成固定值反而可以适应所有场景。该固定值来源于 getHighestNodeSpacing 最小值,修改了下。(会不会是我们的相机其实该值是固定的,根据该值算出的spacing才是有误差的? 如果换了相机是否要改值?)
+            //2022-12-21又换回非固定值。因为有的场景如SS-t-t01myDqnfE的两个数据集密集程度差别很大,应该将稀疏点云的大小设置的大些。 但是这样的缺点是两个数据集因相接处有大有小无法融合。
             this.material.size = base * 5 * num /* * window.devicePixelRatio  */
         } 
         
         
         //console.log('changePointSize  '  + this.dataset_id + '  , num : ' + num + ' , size : ' + this.material.size, this.material.spacing)
-
+    
+        viewer.dispatchEvent('content_changed')     
          
     }  
     
@@ -581,6 +582,7 @@ export class ExtendPointCloudOctree extends PointCloudOctree{
         }
         //console.log('changePointOpacity ' + this.dataset_id + ', num : ' + num + ' , opacity : ' + this.material.opacity) //检查是否做到了低质量时num==opacity,中质量opacity稍小于num,高质量更小
          
+        viewer.dispatchEvent('content_changed') 
     } 
      
 

+ 7 - 5
src/custom/materials/DepthBasicMaterial.js

@@ -18,10 +18,10 @@ export default class DepthBasicMaterial extends THREE.ShaderMaterial{
 			map:             { type: 't', 	value: o.map }, 
             baseColor:     {type:'v3',      value: o.color ?  new THREE.Color(o.color) :  new THREE.Color("#ffffff")},
             backColor:     {type:'v3',      value: o.backColor ?  new THREE.Color(o.backColor) :  new THREE.Color("#ddd")},
-            clipDistance :     { type: 'f', 	value:o.clipDistance || 4}, //消失距离
-            occlusionDistance :     { type: 'f', 	value: o.occlusionDistance || 1 }, //变为backColor距离
-            maxClipFactor :  { type: 'f', 	value: o.maxClipFactor || 1 },  //0-1
-      
+            clipDistance :     { type: 'f', 	value: o.clipDistance || 4 }, //消失距离
+            occlusionDistance :     { type: 'f', 	value:  o.occlusionDistance || 1  }, //变为backColor距离
+            maxClipFactor :  { type: 'f', 	value: o.maxClipFactor || 1 },  //0-1 
+            maxOcclusionFactor :  { type: 'f', 	value: o.maxOcclusionFactor || 1 },  //0-1
 
 		}  
      
@@ -153,7 +153,9 @@ export default class DepthBasicMaterial extends THREE.ShaderMaterial{
             this.uniforms.nearPlane.value = camera.near;
             this.uniforms.farPlane.value = camera.far;
             
-        }            
+        }else{
+            this.uniforms.depthTexture.value
+        }           
     }
 
     

+ 4 - 4
src/custom/materials/ModelTextureMaterial.js

@@ -135,7 +135,7 @@ let shader = {
 
         `,
         fragmentShader: prefixFragment + `
-             
+            #extension GL_EXT_frag_depth : enable
             #define PI 3.141592653 
             
              
@@ -183,7 +183,7 @@ let shader = {
                 return vec2(tx,ty); 
             }
             
-            #extension GL_EXT_frag_depth : enable
+            
             #if defined(GL_EXT_frag_depth) && defined(hasDepthTex)  
                 uniform sampler2D depthMap0;
                 uniform sampler2D depthMap1;
@@ -278,7 +278,7 @@ let shader = {
         `
     }
             
-            
+   //注:gl_FragDepthEXT  修改了确实能像真实mesh那样遮挡住在后面的物体。但是为过渡时不能直接像有模型那样,和角度有关。
 
 export default class ModelTextureMaterial extends THREE.RawShaderMaterial { 
 	constructor( ){ 
@@ -390,7 +390,7 @@ export default class ModelTextureMaterial extends THREE.RawShaderMaterial {
     updateDepthTexEnable(){
         let hasDepthTex = this.pano0 && this.pano1 && this.pano0.pointcloud.hasDepthTex && this.pano1.pointcloud.hasDepthTex  //暂时不知道一个有图一个没图怎么写所以
         
-        Common.addOrRemoveDefine(this, 'hasDepthTex', hasDepthTex?'add':'remove' )
+        Potree.Utils.addOrRemoveDefine(this, 'hasDepthTex', hasDepthTex?'add':'remove' )
         
         
     }

+ 2 - 2
src/custom/materials/postprocessing/OutlinePass.js

@@ -139,7 +139,7 @@ OutlinePass.prototype = Object.assign( Object.create(  Pass.prototype ), {
 					object.visible = bVisible;
 
 				} */
-                viewer.updateVisible(object, 'overlinePass', bVisible)
+                Potree.Utils.updateVisible(object, 'overlinePass', bVisible)
 			}
 
 		}
@@ -196,7 +196,7 @@ OutlinePass.prototype = Object.assign( Object.create(  Pass.prototype ), {
 				if ( ! bFound ) { 
 					 
                     var visibility = object.visible;
-                    viewer.updateVisible(object, 'overlinePass', bVisible) //add 
+                    Potree.Utils.updateVisible(object, 'overlinePass', bVisible) //add 
                     
                     //但保不齐在设置为false后,渲染时又true了,所以在其他地方update时设置visible 得用updateVisible
                      

+ 3 - 3
src/custom/mergeStartTest.js

@@ -528,11 +528,11 @@ var start = function(dom, mapDom, number, fileServer, webSite){ //t-Zvd3w0m
                     transform : { 
                         rotation : [Math.PI/2,  0,   0],
                         position : [0,0,0]  
-                    }  */   
-  
+                    }  */    
+   
                     tilesUrl: 'https://testgis.4dage.com/LVBADUI_qp/tileset.json',
                     transform : { 
-                        rotation : [0,  0,   0],
+                        rotation : [/* Math.PI/2,   */0,  0,   0],
                         position : [0,0,0]   
                     }   
                     

+ 3 - 3
src/custom/modules/CameraAnimation/CameraAnimation.js

@@ -29,7 +29,7 @@ const getLineMat = function(name){
                 color: colors.position,  
                 lineWidth: 2   
             }),
-            aimAtTarget: new THREE.LineBasicMaterial({color:colors.target})
+            aimAtTarget: new THREE.LineBasicMaterial({color:colors.target, depthTest:false})
         }
     }
     return lineMats[name]
@@ -73,7 +73,7 @@ export class CameraAnimation extends THREE.EventDispatcher{
         this.durations = []
         this.quaternions = [];
         
-        if(!Potree.settings.isTest){
+        if(!Potree.settings.isTest && Potree.settings.isOfficial ){
             this.setVisible(false)
         }
         
@@ -173,7 +173,7 @@ export class CameraAnimation extends THREE.EventDispatcher{
                  
             }else if(length >= 2){ 
                 position.copy(this.posCurve.points[index-1].clone().add(this.posCurve.points[index]).multiplyScalar(0.5));
-                target.copy(this.targets[length-1].position.clone().add(this.targets[length]).multiplyScalar(0.5));
+                target.copy(this.targets[index-1].position.clone().add(this.targets[index]).multiplyScalar(0.5));
             }
         }else{
             position.copy(posInfo.position)

+ 6 - 6
src/custom/modules/clipModel/Clip.js

@@ -134,8 +134,8 @@ var Clip = {
         
         Potree.settings.unableNavigate = true
         Potree.settings.ifShowMarker = false
-        viewer.updateVisible(viewer.measuringTool.scene, 'clipModel', false)   
-        //viewer.updateVisible(viewer.mapViewer.cursor, 'clipModel', false)//隐藏地图游标
+        Potree.Utils.updateVisible(viewer.measuringTool.scene, 'clipModel', false)   
+        //Potree.Utils.updateVisible(viewer.mapViewer.cursor, 'clipModel', false)//隐藏地图游标
         viewer.inputHandler.toggleSelection(this.box);
         viewer.inputHandler.fixSelection = true
         viewer.transformationTool.frame.material.color.set(Potree.config.clip.color)//navvis 15899953 
@@ -203,8 +203,8 @@ var Clip = {
         
         Potree.settings.unableNavigate = false
         Potree.settings.ifShowMarker = this.previousView.ifShowMarker
-        viewer.updateVisible(viewer.measuringTool.scene, 'clipModel', true)  
-        //viewer.updateVisible(viewer.mapViewer.cursor, 'clipModel', true) 
+        Potree.Utils.updateVisible(viewer.measuringTool.scene, 'clipModel', true)  
+        //Potree.Utils.updateVisible(viewer.mapViewer.cursor, 'clipModel', true) 
         viewer.setView(this.previousView)
         viewer.setLimitFar(true)
         viewer.setPointStandardMat(false) 
@@ -262,7 +262,7 @@ var Clip = {
         }
         
         
-        var visiPointclouds = viewer.scene.pointclouds.filter(e=> viewer.getObjVisiByReason(e, 'datasetSelection'))
+        var visiPointclouds = viewer.scene.pointclouds.filter(e=> Potree.Utils.getObjVisiByReason(e, 'datasetSelection'))
         let data = {   
             transformation_matrix: visiPointclouds.map((cloud)=>{
                 let data = {
@@ -286,7 +286,7 @@ var Clip = {
     
     downloadNoCrop(){//不剪裁  下载整个点云
         
-        var visiPointclouds = viewer.scene.pointclouds.filter(e=> viewer.getObjVisiByReason(e, 'datasetSelection'))
+        var visiPointclouds = viewer.scene.pointclouds.filter(e=> Potree.Utils.getObjVisiByReason(e, 'datasetSelection'))
         let data = {   
             transformation_matrix: visiPointclouds.map((cloud)=>{
                 let data = {

+ 6 - 6
src/custom/modules/clipping/Clipping.js

@@ -205,7 +205,7 @@ export class Clipping extends THREE.EventDispatcher{ //实时剪裁
         this.shiftTarget = viewer.mainViewport.shiftTarget = new THREE.Vector3 //project在targetPlane上的位置  
 
         this.getAllBoxes().forEach(box=>{
-            viewer.updateVisible(box,'hidden',true)  //显现
+            Potree.Utils.updateVisible(box,'hidden',true)  //显现
         })
         
         viewer.transformationTool.history.clear()
@@ -221,12 +221,12 @@ export class Clipping extends THREE.EventDispatcher{ //实时剪裁
         //隐藏 初始数据集以外的数据集 
         viewer.scene.pointclouds.forEach(e=>{
             if(e.dataset_id!=Potree.settings.originDatasetId){
-                viewer.updateVisible(e,'enterClipping',false) 
+                Potree.Utils.updateVisible(e,'enterClipping',false) 
                 //Potree.settings.floorplanEnables[e.dataset_id] = false 
                 e.panos.forEach(pano=>pano.setEnable(false)) //禁止漫游
                     
             }else{
-                viewer.updateVisible(e,'enterClipping',true, 1, 'add')
+                Potree.Utils.updateVisible(e,'enterClipping',true, 1, 'add')
                 //Potree.settings.floorplanEnables[e.dataset_id] = true 
             }
         })
@@ -245,7 +245,7 @@ export class Clipping extends THREE.EventDispatcher{ //实时剪裁
         
         
         this.getAllBoxes().forEach(box=>{
-            viewer.updateVisible(box,'hidden',false)//隐身
+            Potree.Utils.updateVisible(box,'hidden',false)//隐身
         })
         viewer.transformationTool.removeEventListener('transformed', this.events.transfromCallback)
         //viewer.transformationTool.removeEventListener('stopDrag', this.events.onTransfromEnd)
@@ -257,10 +257,10 @@ export class Clipping extends THREE.EventDispatcher{ //实时剪裁
         //恢复 初始数据集以外的数据集 
         viewer.scene.pointclouds.forEach(e=>{
             if(e.dataset_id!=Potree.settings.originDatasetId){
-                viewer.updateVisible(e,'enterClipping',true) 
+                Potree.Utils.updateVisible(e,'enterClipping',true) 
                 e.panos.forEach(pano=>pano.setEnable(true))
             }else{
-                viewer.updateVisible(e,'enterClipping',false, 0, 'cancel')
+                Potree.Utils.updateVisible(e,'enterClipping',false, 0, 'cancel')
             }
         }) 
         

+ 4 - 4
src/custom/modules/datasetAlignment/Alignment.js

@@ -254,10 +254,10 @@ var Alignment = {
             pointcloud.spriteNodeRoot.matrixWorld.copy(pointcloud.matrixWorld)//.multiplyMatrices(pointcloud.matrixWorld, pointcloud.matrixWorld);	
         } 
 
-        viewer.updateModelBound();
+        viewer.boundNeedUpdate = true
         //pointcloud.updateBound()
         pointcloud.getPanosBound()  
-        
+        viewer.dispatchEvent('content_changed') 
 
     },
     
@@ -294,7 +294,7 @@ var Alignment = {
         this.SplitScreen.split({alignment:true})
          
         viewer.images360.panos.forEach(pano=>{
-            viewer.updateVisible(pano.mapMarker, 'split4Screens', false)
+            Potree.Utils.updateVisible(pano.mapMarker, 'split4Screens', false)
         }) 
         
         viewer.viewports.find(e=>e.name == 'mapViewport').alignment = {rotate:true,translate:true};
@@ -324,7 +324,7 @@ var Alignment = {
         
         this.SplitScreen.recover()
         viewer.images360.panos.forEach(pano=>{
-            viewer.updateVisible(pano.mapMarker, 'split4Screens', true)
+            Potree.Utils.updateVisible(pano.mapMarker, 'split4Screens', true)
         }) 
         this.editing = false
         this.history.clear() 

+ 4 - 4
src/custom/modules/mergeModel/MergeEditor.js

@@ -95,7 +95,7 @@ let MergeEditor = {
             }); 
             this.transformControls.setSize(1.5)
             viewer.scene.scene.add(this.transformControls2) 
-            viewer.setObjectLayers(this.transformControls2, 'layer2' )  
+            Potree.Utils.setObjectLayers(this.transformControls2, 'layer2' )  
              
              
             let mouseDown = (e)=>{
@@ -166,7 +166,7 @@ let MergeEditor = {
         viewer.ssaaRenderPass.enabled = false
         viewer.outlinePass.enabled = true
         //Potree.settings.intersectWhenHover = false
-        //viewer.updateVisible(viewer.reticule, 'force', false)
+        //Potree.Utils.updateVisible(viewer.reticule, 'force', false)
         
         viewer.mainViewport.camera.near = 0.05; // too small will result in z-fighting
         
@@ -322,7 +322,7 @@ let MergeEditor = {
         
         viewer.viewports[1].layersAdd('layer2') 
         viewer.viewports[0].layersAdd('layer1') 
-        viewer.setObjectLayers(this.transformControls, 'layer1' ) 
+        Potree.Utils.setObjectLayers(this.transformControls, 'layer1' ) 
         this.transformControls.view = viewer.viewports[0].view
         this.transformControls.camera = viewer.viewports[0].camera
         this.transformControls._gizmo.hideAxis = {translate:['z'], rotate:['x','y','z'] }
@@ -355,7 +355,7 @@ let MergeEditor = {
         this.transformControls.camera = viewer.viewports[0].camera
         this.transformControls.view = viewer.viewports[0].view 
         this.transformControls._gizmo.hideAxis = {rotate:['e']}
-        viewer.setObjectLayers(this.transformControls, 'sceneObjects' )  //恢复
+        Potree.Utils.setObjectLayers(this.transformControls, 'sceneObjects' )  //恢复
         
         
         viewer.compass.changeViewport(viewer.viewports[0]) //恢复 

+ 128 - 52
src/custom/modules/panoEdit/panoEditor.js

@@ -58,7 +58,11 @@ const cameraProps = [
         axis:["y","z"], 
         direction : new THREE.Vector3(1,0,0), 
         openCount:0,
-    }  
+    },
+    {
+        name : 'mainView',
+        openCount:0,
+    }
 ]   
 
 
@@ -84,7 +88,8 @@ class PanoEditor extends THREE.EventDispatcher{
     }
      
     init(){ 
-    
+        
+        
         {//init lineMats
             lineMats.default = LineDraw.createFatLineMat({
                 color: '#eeeeee',
@@ -120,7 +125,7 @@ class PanoEditor extends THREE.EventDispatcher{
             this.lineMeshes.name = 'lineMeshes'
             viewer.scene.scene.add(this.lineMeshes)
             
-            
+            Potree.settings.ifShowMarker = false
             
             {
                 this.transformControls = new TransformControls(viewer.mainViewport.camera, viewer.renderArea,{
@@ -214,7 +219,7 @@ class PanoEditor extends THREE.EventDispatcher{
             
             viewer.addEventListener('global_click',(e)=>{
                 if(e.button === THREE.MOUSE.RIGHT){//取消旋转和平移
-                     console.log('right click',e)
+                     //console.log('right click',e)
                      this.setLinkOperateState('addLink',false)
                      this.setLinkOperateState('removeLink',false)
                 }else if(this.clickToZoomInEnabled){
@@ -270,8 +275,9 @@ class PanoEditor extends THREE.EventDispatcher{
                         endPos = e.intersect.point.position
                     }
                     
-                    LineDraw.updateLine(this.linkGuideLine, [this.selectedPano.position, endPos] ) 
-                    this.linkGuideLine.visible = true
+                    LineDraw.updateLine(this.linkGuideLine, [this.selectedPano.position, endPos] )  
+                    this.linkGuideLine.visible = true 
+                    viewer.dispatchEvent('content_changed')  
                 }
                 
                 viewer.addEventListener('global_mousemove', (e)=>{
@@ -290,7 +296,29 @@ class PanoEditor extends THREE.EventDispatcher{
                     this.setTranMode('translate') 
                 }
             }) */      
+            {
+                let changed
+                viewer.addEventListener('camera_changed', (e)=>{
+                    changed = true
+                    Common.intervalTool.isWaiting('updatePointLevels', ()=>{  
+                        if(changed){
+                            changed = false
+                            this.updatePointLevels()
+                            return true
+                        }
+                    }, 1050)
+                })
+
+                setTimeout(()=>{ 
+                    this.updatePointLevels()
+                }, viewer.scene.pointclouds.length*150)  //等待差不多updat出了正确的visibleNode时                
+            }
+            
+            
             
+            this.panoReposCallback = ()=>{
+                viewer.controls.setTarget(this.selectedPano.position) //3d时绕其为中心转动
+            }
         }) 
     }
     
@@ -343,9 +371,10 @@ class PanoEditor extends THREE.EventDispatcher{
         this.cameras.mainView = viewer.mainViewport.camera
          
         
-    } 
+    }  
     
-    switchView(name){//替换view和camera到mainViewport
+    switchView(name ){//替换view和camera到mainViewport
+         
         let view = this.views[name]
         let camera = this.cameras[name]
         let prop = cameraProps.find(e=>e.name == name)
@@ -367,20 +396,31 @@ class PanoEditor extends THREE.EventDispatcher{
         
         viewer.updateScreenSize({forceUpdateSize:true})//更新camera aspect  left等
         this.updateCursor()
-        
-        
-        
-        
+         
         if(name == 'mainView'){ 
             viewer.mainViewport.alignment =  null
-            viewer.scene.pointclouds.forEach(e=>{
-                e.material.activeAttributeName = 'rgba' 
-                e.material.useFilterByNormal = false  
-                e.changePointOpacity(1 )
-                 
-            })
-            viewer.updateVisible(viewer.reticule, 'force', true)
              
+            let changeMat = ()=>{
+                viewer.scene.pointclouds.forEach(e=>{
+                    e.material.activeAttributeName = 'rgba' 
+                    e.material.useFilterByNormal = false  
+                    e.changePointOpacity(1 )  
+                })
+            }
+            if(prop.openCount == 0){ //点数较多时,首次转到3D视角会卡顿,因为要切换材质。
+                let delay1 = THREE.Math.clamp(viewer.scene.pointclouds.length*0.5, 1, 200) 
+                setTimeout(()=>{
+                    this.activeViewName == 'mainView' && changeMat() 
+                },delay1)  
+                //console.log('switchview',delay1 )
+            }else{
+                changeMat() 
+            }
+            
+             
+            
+            Potree.Utils.updateVisible(viewer.reticule, 'force', true)
+                
             if(lastView){//2d->3d
                 
                 view.copy(lastView)
@@ -475,7 +515,7 @@ class PanoEditor extends THREE.EventDispatcher{
                 } 
             }
              
-            prop.openCount ++;
+            
             
             
             
@@ -491,7 +531,7 @@ class PanoEditor extends THREE.EventDispatcher{
                 }
                 
             })
-            viewer.updateVisible(viewer.reticule, 'force', false)      
+            Potree.Utils.updateVisible(viewer.reticule, 'force', false)      
             
             if(name == 'top') viewer.mainViewport.alignment = {rotate:true,translate:true};
             if(name == 'right'){
@@ -505,10 +545,15 @@ class PanoEditor extends THREE.EventDispatcher{
         } 
         
         
+       
         this.updateTranCtl()
         this.setTranMode(this.tranMode) // update
         this.setZoomInState(false) //取消放大模式
-        this.updatePointLevels()
+        this.updatePointLevels() 
+       
+         
+        
+        prop.openCount ++; 
     }
     
     
@@ -641,8 +686,8 @@ class PanoEditor extends THREE.EventDispatcher{
     
     switchPanoVisible(pano, v, informBy2d){ 
         pano.circle.visible = v   
-        viewer.updateVisible(pano, 'panoEditor', v)
-        viewer.updateVisible(pano.pointcloud, 'panoEditor', v)
+        Potree.Utils.updateVisible(pano, 'panoEditor', v)
+        Potree.Utils.updateVisible(pano.pointcloud, 'panoEditor', v)
         if(v){
             this.visiblePanos.includes(pano) || this.visiblePanos.push(pano)
         }else{
@@ -655,7 +700,19 @@ class PanoEditor extends THREE.EventDispatcher{
         }
          
         informBy2d || this.dispatchEvent({type:"switchPanoVisible", pano, v})
-        this.updatePointLevels()
+        
+        {
+            this.updatedPL_ = true
+            setTimeout(()=>{
+                Common.intervalTool.isWaiting('updatePointLevels2', ()=>{  
+                    if(this.updatedPL_){
+                        this.updatedPL_ = false
+                        this.updatePointLevels()
+                        return true
+                    }
+                }, 50)
+            },1)//等update过visibleNodes
+        }
     } 
      
     
@@ -740,7 +797,7 @@ class PanoEditor extends THREE.EventDispatcher{
         }else{
             viewer.dispatchEvent({type : "CursorChange", action : "remove",  name:"disconnectPano"} )
         }
-        
+        viewer.dispatchEvent('content_changed') 
     } 
      
       
@@ -759,7 +816,7 @@ class PanoEditor extends THREE.EventDispatcher{
             })
         })
         
-        console.log('panoLink',this.panoLink)
+        //console.log('panoLink',this.panoLink)
     }
      
     
@@ -913,19 +970,18 @@ class PanoEditor extends THREE.EventDispatcher{
             depthWrite: false,  
         }) */
         window.circleMats = circleMats
+       
         circleMats.default_normal = new DepthBasicMaterial({
             map,
             color: 0xffffff,
-            transparent: true,
-            /* depthTest: false,
-            depthWrite: false, */ 
-            clipDistance : 5,//消失距离
-            occlusionDistance: 2,//变为backColor距离   
+            transparent: true, 
             useDepth:true,
-            maxClipFactor: 0.6,
             backColor: 0x33ffdd,
+            occlusionDistance: 10,//变为backColor距离 
+            clipDistance : 5,//消失距离            
+            maxClipFactor: 0.8,  
+            maxOcclusionFactor: 0.8,
         }) 
-        
         circleMats.default_rtk_on = circleMats.default_normal.clone();
         circleMats.default_rtk_on.map = texLoader.load(Potree.resourcePath+'/textures/rtk-y-n.png' )  
         circleMats.default_rtk_off = circleMats.default_normal.clone();
@@ -1080,6 +1136,9 @@ class PanoEditor extends THREE.EventDispatcher{
             
             this.selectedPano.circle.material = circleMats['default' + '_'+ this.getPanoRtkState(this.selectedPano) ] 
             this.selectedPano.circle.renderOrder = renderOrders.circle 
+ 
+            this.selectedPano.removeEventListener('rePos',this.panoReposCallback)
+
 
             if(this.activeViewName == 'mainView'){
                  
@@ -1102,7 +1161,11 @@ class PanoEditor extends THREE.EventDispatcher{
         if(pano){
             this.selectedPano.circle.material = circleMats['selected' + '_'+ this.getPanoRtkState(this.selectedPano) ] 
             this.selectedPano.circle.renderOrder = this.selectedPano.circle.pickOrder = renderOrders.circleSelected //侧视图能显示在最前
-             
+            
+            viewer.controls.setTarget(this.selectedPano.position) //3d时绕其为中心转动 
+            this.selectedPano.addEventListener('rePos',this.panoReposCallback)
+
+            
             if(this.activeViewName == 'mainView'){
                 
             }else{
@@ -1111,9 +1174,7 @@ class PanoEditor extends THREE.EventDispatcher{
                     e.material.color = pointColor.selected;  
                 })
             }
-            
-            
-            
+             
             
             {//自动切换楼层
                
@@ -1126,14 +1187,17 @@ class PanoEditor extends THREE.EventDispatcher{
                 
                 this.gotoFloor(atFloor, false, 600   ) 
             }
-                
-            
+                 
+        }else{
+            viewer.controls.setTarget(null)  
         }
         
         
         this.updateCursor() 
         this.updateTranCtl()
 
+        
+
 
         if(informinformBy2d){
             if(this.selectedPano){
@@ -1150,27 +1214,39 @@ class PanoEditor extends THREE.EventDispatcher{
         }else{
             this.dispatchEvent({type:'panoSelect', pano })
         } 
+        
+         
+        
+        viewer.dispatchEvent('content_changed') 
     }
     
     
+    
     updatePointLevels(){
-        let percent = 1
+        if(this.pauseUpdateLevels)return
+        let maxBudget = Potree.config.pointDensity.panoEdit.pointBudget
+        let visiCount1 = viewer.scene.pointclouds.filter(e=>e.visible).length
+        let visiCount2 = viewer.scene.pointclouds.filter(e=>e.visibleNodes.length>0).length //屏幕范围内可见的个数
+        let maxCount = 200, minCount = 1,  minPer = 0.45/* 0.4 */, maxPer = 1
+        let percent1 = maxPer - ( maxPer - minPer) * THREE.Math.clamp((visiCount1 - minCount)  / (maxCount - minCount),0,1)   
+        let percent2 = maxPer - ( maxPer - minPer) * THREE.Math.clamp((visiCount2 - minCount)  / (maxCount - minCount),0,1)   
+        let percent = percent1*percent2
+        
         if(this.activeViewName == 'mainView'){
             //假设每个pointcloud所带的点个数大致相同,那么当可见点云个数越多,所能展示的level越低,否则因总个数超过budget的话密度会参差不齐。
-            let visiCount = viewer.scene.pointclouds.filter(e=>e.visible).length
-            let maxCount = 70, minCount = 1,  minPer = 0.4, maxPer = 1
-            percent = maxPer - ( maxPer - minPer) * THREE.Math.clamp((visiCount - minCount)  / (maxCount - minCount),0,1)   
+            
             //pointcloud.changePointSize()
             //console.log('updatePointLevels', percent, visiCount) 
-        
-        }else{
-            percent = null
+            Potree.settings.UserDensityPercent = Math.sqrt(percent2) 
+            viewer.setPointBudget(maxBudget * percent2)
+        }else{ 
+            Potree.settings.UserDensityPercent = 1 
+            viewer.setPointBudget(maxBudget * percent) 
         }
+         
+        viewer.setPointLevels() 
         
-        
-        Potree.settings.UserDensityPercent = percent 
-        viewer.setPointLevels()
-             
+        console.warn('setPointBudget', Potree.pointBudget, visiCount1,visiCount2,  Potree.settings.UserDensityPercent)
     }
     
     getPanoRtkState(pano){
@@ -1291,7 +1367,7 @@ class PanoEditor extends THREE.EventDispatcher{
             }
         }
         
-        console.log(sweepLocations)
+        //console.log(sweepLocations)
         return sweepLocations
     }
 }

+ 8 - 4
src/custom/modules/panos/DepthImageSampler.js

@@ -42,6 +42,9 @@ class DepthImageSampler {
     
     sample( intersect, currentPano, onlyPos ) {//通过和skybox的intersect得到真实的intersect的位置
         if(!intersect)return
+        
+          
+        
         let location = new THREE.Vector3
         let normal
         currentPano = currentPano || viewer.images360.currentPano
@@ -98,8 +101,10 @@ class DepthImageSampler {
           , pT = this.getNearbyPoint(origin, uv,  0, 1);
            
         } */
-        
-        //console.log('normal',normal)
+         
+          
+     
+        //console.log(location, normal,  distance)
           
         return {location, normal,  distance} 
     }
@@ -202,8 +207,7 @@ class DepthImageSampler {
 
 /* 
     注:
-    
-    当前测试的图不太对,三个通道都一样了,所以几乎是整数的depth。法线也几乎都朝向相机
+     
 
     由于有时候获取intersect需要知道是哪个点云,所以还是不能用这个。如加测量线。
 

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 501 - 1171
src/custom/modules/panos/Images360.js


+ 34 - 87
src/custom/modules/panos/Panorama.js

@@ -11,7 +11,10 @@ var texLoader = new THREE.TextureLoader()
 
 
                                                                          
-                                         
+const markerOpacitys ={
+    default : 0.5,
+    hovered : 1,
+}
 
 const labelProp = {
     sizeInfo: {minSize : 200 ,  maxSize : 250,   nearBound : 0.8, farBound : 10},
@@ -35,7 +38,7 @@ const labelProp2 = {
 
 let standardMarkerMat 
 let markerTex
-let getMarerMat = function(){
+let getMarkerMat = function(){
     if(!markerTex) {
         markerTex = {
             default:texLoader.load( Potree.resourcePath+'/textures/marker.png' ),
@@ -46,7 +49,7 @@ let getMarerMat = function(){
         //有可能被点云遮住吗。 
      
     }
-    return  new DepthBasicMaterial({opacity:0.7, side: THREE.DoubleSide , map:markerTex.default ,transparent:true, 
+    return  new DepthBasicMaterial({opacity: markerOpacitys.default, side: THREE.DoubleSide , map:markerTex.default ,transparent:true, 
         clipDistance: 2,  occlusionDistance:1,  //不能设置太短,因为过渡时深度不准确
         //depthTest: !!Potree.settings.useDepthTex,
         useDepth:  !!Potree.settings.useDepthTex
@@ -86,16 +89,16 @@ class Panorama extends THREE.EventDispatcher{
         super()
         this.id = o.id; //唯一标识
         this.images360 = images360
-        this.visible = true  //for viewer updateVisible
+        this.visible = true  //for   updateVisible
         this.enabled = true//是否可以走
         this.addEventListener('isVisible',(e)=>{//是否显示该点的mesh(不显示也能走)
             //console.log('pano isVisible', this.id, e.visible) 
-            viewer.updateVisible(this.marker, 'panoVisi', e.visible)
+            Potree.Utils.updateVisible(this.marker, 'panoVisi', e.visible)
             Potree.settings.showPanoMesh && (this.mesh.visible = e.visible)
             if(e.reason == 'screenshot' || e.visible){
                 this.label && (this.label.visible = e.visible)//截图时隐藏下
             }
-            viewer.updateVisible(this.label2, 'panoVisi', e.visible)
+            Potree.Utils.updateVisible(this.label2, 'panoVisi', e.visible)
         })
         /*  
         漫游点可见性:旧
@@ -242,7 +245,7 @@ class Panorama extends THREE.EventDispatcher{
 
 
     setEnable(enable){//是否可以走
-        viewer.updateVisible(this, 'isEnabled', enable) //令所有marker不可见
+        Potree.Utils.updateVisible(this, 'isEnabled', enable) //令所有marker不可见
 
         this.enabled = enable 
         //如果当前在全景模式且在这个点,需要切换显示吗? 目前用不到 
@@ -258,6 +261,7 @@ class Panorama extends THREE.EventDispatcher{
             this.depthTex = texture
             this.images360.dispatchEvent({type:'loadedDepthImg', pano:this, loaded:true})
             this.depthTexLoading = false
+            //viewer.dispatchEvent('content_changed') 
         },null,(e)=>{//error
             console.error('loadDepthImg失败, 数据集sceneCode'+ this.pointcloud.sceneCode,  this.id )
             this.pointcloud.hasDepthTex = false
@@ -270,32 +274,9 @@ class Panorama extends THREE.EventDispatcher{
 	}
  
     
-    build(){
-          
-        /* let mesh = new THREE.Mesh(sg, sm); 
-        mesh.scale.set(1, 1, 1);
-        mesh.material.transparent = true;
-        mesh.material.opacity = 0.75;
-        mesh.pano = this;
-        mesh.name = 'panoSphere'
-        mesh.addEventListener('mouseover',(e)=>{
-            mesh.material = smHovered
-        })
-        mesh.addEventListener('mouseleave',(e)=>{
-            mesh.material = sm
-        })
-        mesh.addEventListener('click',(e)=>{
-            this.images360.focusPano(this)
-        }) 
-        this.mesh = mesh;
-        if(!Potree.settings.showPanoMesh) mesh.visible = false
-        this.images360.node.add(mesh)
-        */
+    build(){ 
         
-        { // orientation
-            //var {course, pitch, roll} = this;
-            //mesh.quaternion.copy(this.quaternion) 
-             
+        { // orientation 
             //add 
             //var quaternion = new THREE.Quaternion().multiplyQuaternions(this.quaternion,  rot901);//改  为球目全
             //quaternion.premultiply(rot90)
@@ -308,10 +289,8 @@ class Panorama extends THREE.EventDispatcher{
             //console.log(this.quaternion)
             //this.quaternion = quaternion
         } 
-        
-        
          
-        let marker = new THREE.Mesh(planeGeo, getMarerMat() ) 
+        let marker = new THREE.Mesh(planeGeo, getMarkerMat() ) 
             marker.name = 'marker_'+this.id
             marker.up.set(0,0,1)
             marker.lookAt(marker.up) 
@@ -321,31 +300,11 @@ class Panorama extends THREE.EventDispatcher{
         })    
              
         this.marker = marker 
-        if(Potree.settings.editType == 'pano'){
-            viewer.updateVisible(marker, 'panoEdit', false, 4)
-        }
         
         this.images360.node.add(marker)
         Potree.settings.isTest && this.createTextLabel()
         this.createTextLabel2() 
-        
-        /* let mouseover = (e)=>{ 
-            if(!e.byMap){
-                pano.mapMarker.material = panoMarkerMats.selected
-                if(!e.byMainView) pano.dispatchEvent({type: "hoverOn", byMap:true})
-                this.needRender = true    
-            }
-        }
-        
-        let mouseleave = (e)=>{
-            if(!e.byMap){
-                pano.mapMarker.material = panoMarkerMats.default
-                if(!e.byMainView) pano.dispatchEvent({type: "hoverOff", byMap:true})
-                this.needRender = true
-            }
-        } */
          
-        
         marker.addEventListener('mouseover', this.hoverOn.bind(this));  
         marker.addEventListener('mouseleave', this.hoverOff.bind(this)); 
     }
@@ -404,8 +363,10 @@ class Panorama extends THREE.EventDispatcher{
     
     
     hoverOn(e={}) { 
-        //console.log("hoverOn  " + this.id  )
-        transitions.start(lerp.property(this.marker.material, "opacity", 1), 250)  
+        //console.log("hoverOn  " + this.id  ) 
+        transitions.start(lerp.property(this.marker.material, "opacity", markerOpacitys.hovered,()=>{
+            viewer.dispatchEvent('content_changed')
+        }), this.marker.visible ? 250 : 0)  
 		if(!e.byMap) this.dispatchEvent({type:'hoverOn', byMainView:true})
         if(!e.byImages360) this.images360.dispatchEvent({type:'markerHover', hovered:true, pano:this})
     }
@@ -415,7 +376,9 @@ class Panorama extends THREE.EventDispatcher{
 
     hoverOff(e={}){
         //console.log("hoverOff  " + this.id  )
-        transitions.start(lerp.property(this.marker.material, "opacity", 0.5), 250) 
+        transitions.start(lerp.property(this.marker.material, "opacity", markerOpacitys.default,()=>{
+            viewer.dispatchEvent('content_changed')
+        }), this.marker.visible ? 250 : 0) 
         if(!e.byMap) this.dispatchEvent({type:'hoverOff',  byMainView:true})
         if(!e.byImages360) this.images360.dispatchEvent({type:'markerHover', hovered:false, pano:this})
     }
@@ -437,23 +400,14 @@ class Panorama extends THREE.EventDispatcher{
         //console.log("enter pano "+ this.id)
     } 
 
-    exit(){
-        /* if(this.tiled)
-        { */
-            this.clearWaitDeferreds();
-            this.minimumTiledPanoLoaded = !1;
-            this.tiledPanoRenderTarget = null;
-            this.setZoomed(!1);
-            this.images360.panoRenderer.deactivateTiledPano(this);
-            this.highestPartialTileRenderOpCompleted = 0;
-            this.highestFullTileRenderOpCompleted = 0;
-        /*}
-         else
-        {
-            this.solidSkybox.dispose();
-            this.solidSkybox.loaded = !1;
-            this.solidSkybox.version = 0;
-        } */
+    exit(){ 
+        this.clearWaitDeferreds();
+        this.minimumTiledPanoLoaded = !1;
+        this.tiledPanoRenderTarget = null;
+        this.setZoomed(!1);
+        this.images360.panoRenderer.deactivateTiledPano(this);
+        this.highestPartialTileRenderOpCompleted = 0;
+        this.highestFullTileRenderOpCompleted = 0;
         
         //console.log("exit pano "+ this.id)
         
@@ -573,16 +527,7 @@ class Panorama extends THREE.EventDispatcher{
         this.floorPosition && this.label.position.copy(this.floorPosition)
     }
     
-    createTextLabel2(){  
-                          
-                                                                                           
-                                                            
-                                                       
-                                                         
-                              
-                               
-                           
-                        
+    createTextLabel2(){   
           
         this.label2 = new TextSprite(Object.assign({},
            labelProp2, {text: /* this.originID  */   parseInt(this.id)+1   }) //{text: `id:${this.id}, dataset:${this.pointcloud.name}, 4dkkId:${this.originID}`}
@@ -591,7 +536,7 @@ class Panorama extends THREE.EventDispatcher{
         this.floorPosition && this.label2.position.copy(this.floorPosition)
         let s = 0.4
         this.label2.scale.set(s,s,s)
-        viewer.updateVisible(this.label2, 'notDisplay', false)
+        Potree.Utils.updateVisible(this.label2, 'notDisplay', false)
     }
     
     removeTextLabel(){
@@ -682,6 +627,7 @@ Panorama.prototype.loadTiledPano = function() {
                         var i = this.getWaitDeferred(ev.size).deferred;//"pending"为还未完成
                         i && "pending" === i.state() && this.highestPartialTileRenderOpCompleted >= ev.size && (i.resolve(ev.size, ev.count),
                         this.resetWaitDeferred(ev.size))//恢复active为false
+                         
                     }.bind(this)) 
                     
                     this.addEventListener(PanoramaEvents.LoadFailed, function(ev) {
@@ -719,7 +665,7 @@ Panorama.prototype.loadTiledPano = function() {
                             } 
                         } 
 
-
+                        viewer.dispatchEvent('content_changed') 
     
                         
                         /* var r = this.getWaitDeferred(ev.size).deferred;
@@ -744,6 +690,7 @@ Panorama.prototype.loadTiledPano = function() {
             this.images360.tileDownloader.forceQueueTilesForPano(this, size, dir, h, u, download) 
             this.tiledPanoRenderTarget = this.images360.panoRenderer.activateTiledPano(this, this.images360.qualityManager.getMaxNavPanoSize(), o) 
             this.images360.panoRenderer.renderPanoTiles(this.id, dirs, a)
+            
         }else{
             //console.log('早已经全加载好了' +size, this.id)
             c.resolve(size)

+ 12 - 10
src/custom/modules/panos/tile/PanoRenderer.js

@@ -29,9 +29,11 @@ function createDescriptor() {
 function upload() { 
     if (!this.uploadIntervalCancelled) {
         if (this.overlayTilesLoaded || !this.usingTileOverlay) {
-            b = !0  
-            this.updateUploadQueue(this.maxNonBaseUploadsPerFrame, this.maxBaseUploadsPerFrame),
-            this.peekNextFromUploadQueue() ? this.refreshUploadInterval(w) : this.uploadInterval = null
+            b = !0   
+            let maxNonBaseUploadsPerFrame = viewer.mainViewport.view.isFlying() ? 1 : this.maxNonBaseUploadsPerFrame //原先2。这是每帧uploadTile非512的瓦片tex的数量。之前的2太卡了,降为1。(检测卡顿方法:在一个pano点旋转至所有2048的tile都加载完,然后之后到这个点看看卡不卡。因为该点tiles都下载完了所以会在飞过来时陆续都加载,所以容易卡)
+            this.updateUploadQueue(maxNonBaseUploadsPerFrame, this.maxBaseUploadsPerFrame) 
+            let time = viewer.mainViewport.view.isFlying() ? 60 : w  //add 飞行有时候会卡,增长间隔 
+            this.peekNextFromUploadQueue() ? this.refreshUploadInterval(time) : this.uploadInterval = null  //定时下一次更新
         } else {
             this.refreshUploadInterval(this.uploadIntervalDelay)
         }
@@ -41,8 +43,8 @@ function upload() {
 var b = !1,
     w = config.tiling.uploadIntervalDelay,
     _ = config.tiling.initialIntervalDelay,
-    T = config.tiling.maxNonBaseUploadsPerFrame,
-    x = config.tiling.maxBaseUploadsPerFrame,
+    T = config.tiling.maxNonBaseUploadsPerFrame,//2   size>512的每次只upload这么多个
+    x = config.tiling.maxBaseUploadsPerFrame,//6
     S = {
         Base: 0,
         Remaining: 1
@@ -998,7 +1000,7 @@ PanoRenderer.prototype.renderToCubeMap = function() {
         plane = null,
         l = 1;
     return function(texture, renderTarget, tileWidth, tileHeight, startXinTile, startYinTile, widthinTile, heightinTile, startX, startY, width, height, cubeFace, E, b, w) {
-         
+           
           
         var renderer =  this.viewer.renderer; 
         
@@ -1021,7 +1023,7 @@ PanoRenderer.prototype.renderToCubeMap = function() {
                 fragmentShader: Shaders['basicTextured.fs'],
                 depthWrite: !1,
                 depthTest: !1,
-                side: THREE.DoubleSide
+                side: 0,//THREE.DoubleSide
             }),
             geo = new THREE.PlaneBufferGeometry(l, l),
             plane = new THREE.Mesh(geo, material),
@@ -1071,14 +1073,14 @@ PanoRenderer.prototype.renderToCubeMap = function() {
             posArr[9] = D + B,
             posArr[10] = N;
             
-        renderer.properties.get(scene); 
+        //renderer.properties.get(scene); 
         material.uniforms.map.value = texture;
         material.blending = E || THREE.NoBlending,
         material.transparent = !!b 
         
         void 0 !== w && null !== w || (w = 1),
         material.uniforms.opacity.value = w,
-        material.needUpdate = !0  
+     //   material.needUpdate = !0  
         //renderTarget.activeCubeFace = cubeFace, //0-5 应该是指定渲染h中的面  失效
         /* renderer.setScissorTest(!0)  
         //指定绘制区域,类似遮罩(相对于屏幕)
@@ -1162,7 +1164,7 @@ PanoRenderer.prototype.copyCubeMap = function() {//将texture渲染到zoomRender
             
             /* testCube = mesh.clone();  
             viewer.scene.scene.add(testCube);
-            viewer.setObjectLayers(testCube, 'sceneObjects') 
+            Potree.Utils.setObjectLayers(testCube, 'sceneObjects') 
              */
         }
         let autoClear = this.viewer.renderer.autoClear

+ 6 - 6
src/custom/modules/panos/tile/TileDownloader.js

@@ -44,15 +44,15 @@ class TileDownloader extends THREE.EventDispatcher{
          
         viewer.addEventListener('pageVisible', (e)=>{//不可见时不refreshUpdateInterval 
             //console.log('visibilitychange:', state)
-            viewer.updateVisible(this,  'pageVisible', e.v) 
+            Potree.Utils.updateVisible(this,  'pageVisible', e.v) 
             this.judgeStart() 
         }) 
         
-        this.visible = true //add   借用viewer.updateVisible来判断是否start
+        this.visible = true //add   借用Potree.Utils.updateVisible来判断是否start
         if(Potree.settings.useDepthTex){
             this.judgeStart()  //开始下载depthTex
         }else{ 
-            viewer.updateVisible(this,'showPanos', false ) //默认visible = false
+            Potree.Utils.updateVisible(this,'showPanos', false ) //默认visible = false
         }
         
     }
@@ -66,7 +66,7 @@ class TileDownloader extends THREE.EventDispatcher{
     start() { 
         this.downloadCubeTex = true 
         if(!Potree.settings.useDepthTex){
-            viewer.updateVisible(this,'showPanos', true )
+            Potree.Utils.updateVisible(this,'showPanos', true )
             this.judgeStart()            
         }else{
             this.refreshInterval || this.judgeStart()
@@ -76,7 +76,7 @@ class TileDownloader extends THREE.EventDispatcher{
     stop() {
         this.downloadCubeTex = false
         if(!Potree.settings.useDepthTex){
-            viewer.updateVisible(this,'showPanos', false )
+            Potree.Utils.updateVisible(this,'showPanos', false )
             this.judgeStart()
         } 
     }
@@ -452,7 +452,7 @@ TileDownloader.prototype.getTileUrl = function() {
             tileSize = o.tileSize,
             tileIndex = o.tileIndex,
             sceneCode = o.pano.pointcloud.sceneCode,
-            useV4url = Potree.settings.testV4url && o.pano.pointcloud.datasetData.sceneVersion == 'V4'        //v4的全景图等路径不一样  
+            useV4url = Potree.settings.useV4url && o.pano.pointcloud.datasetData.sceneVersion == 'V4'        //v4的全景图等路径不一样  
         var metadata = {sceneScheme:10}  
         
         

+ 22 - 26
src/custom/modules/route/RouteGuider.js

@@ -6,7 +6,7 @@ import Common from "../../utils/Common.js";
 import browser from '../../utils/browser.js' 
 
 const texLoader = new THREE.TextureLoader()
-const arrowSpacing = 1 //间隔
+const arrowSpacing = 1  //间隔
 const arrowSize = arrowSpacing * 0.5
 const planeGeo = new THREE.PlaneBufferGeometry(1,1);
 
@@ -33,40 +33,34 @@ export class RouteGuider extends THREE.EventDispatcher{
     init(){
         if(this.inited) return;
         
-        let zoom;
+        let zoom, resolution=new THREE.Vector2;
         viewer.mapViewer.addEventListener('camera_changed', e => {
             if(!this.routeStart || !this.routeEnd) return   
             var camera = e.viewport.camera
            
             Common.intervalTool.isWaiting('routeCameraInterval', ()=>{ //延时update,防止卡顿
-                if(camera.zoom != zoom){ 
+                if(camera.zoom != zoom || !resolution.equals(e.viewport.resolution)){ 
                     //console.log('updateMapArrows')
                     this.updateMapArrows(true)
-                    zoom = camera.zoom         
+                    zoom = camera.zoom; resolution.copy(e.viewport.resolution)  
                     return true 
                 } 
             }, browser.isMobile()?500:200)
         })
-        
-   
-        
-       
-        //let lastPos = new THREE.Vector3
+         
+        let lastPos = new THREE.Vector3 
         viewer.addEventListener('camera_changed', e => {
             if(!this.routeStart || !this.routeEnd || !e.changeInfo.positionChanged) return
-            Common.intervalTool.isWaiting('routeCameraInterval', ()=>{ //延时update,防止卡顿
-                //let currPos = viewer.scene.getActiveCamera().position
+            Common.intervalTool.isWaiting('routeCameraInterval2', ()=>{ //延时update,防止卡顿
+                let currPos = viewer.scene.getActiveCamera().position
              
-                //if(!currPos.equals(lastPos)){
-                   // lastPos.copy(currPos)
+                if(!currPos.equals(lastPos)){
+                    lastPos.copy(currPos)
                     this.updateArrowDisplay() 
                      
                     return true 
-                //}
-            }, 1000)
-            
-            
-                        
+                }
+            }, 1000)          
         })
         
         
@@ -108,7 +102,7 @@ export class RouteGuider extends THREE.EventDispatcher{
             map
         }))
         this.arrow.scale.set(arrowSize,arrowSize,arrowSize)
-        viewer.setObjectLayers(this.arrow, 'sceneObjects' )
+        Potree.Utils.setObjectLayers(this.arrow, 'sceneObjects' )
          
         
         /* this.testArrow = this.arrow.clone();
@@ -118,7 +112,7 @@ export class RouteGuider extends THREE.EventDispatcher{
         this.arrows = new THREE.Object3D;
         this.sceneMeshGroup.add(this.arrows)
         
-        viewer.setObjectLayers(this.sceneMeshGroup, 'sceneObjects' )
+        Potree.Utils.setObjectLayers(this.sceneMeshGroup, 'sceneObjects' )
         //this.sceneMeshGroup.traverse(e=>e.renderOrder = 90)
         
         
@@ -536,7 +530,8 @@ export class RouteGuider extends THREE.EventDispatcher{
     updateMapArrows(ifReset){
         if(this.route.length == 0)return  
         var zoom = viewer.mapViewer.camera.zoom
-        let count = Math.max(2,Math.round(this.routeLength * zoom  / arrowSpacing / 25))//点数
+        let isBig = viewer.mapViewer.viewports[0].resolution.y > 300  
+        let count = Math.max(2,Math.round(this.routeLength * zoom  / arrowSpacing / (isBig?35:30)))//点数
         
         if(count == this.mapPoints.length+1)return//没变
 
@@ -546,8 +541,8 @@ export class RouteGuider extends THREE.EventDispatcher{
         this.mapPoints = mapPoints
         
         
-        var scale = 25/zoom
-        this.mapArrow.scale.set(scale*0.6,scale*0.6,scale*0.6) 
+        var scale = (isBig ? 26 : 22)/zoom
+        this.mapArrow.scale.set(scale,scale,scale) 
         /* this.mapMarkStart.scale.set(scale,scale,scale) 
         this.mapMarkEnd.scale.set(scale,scale,scale)  */
         
@@ -560,7 +555,7 @@ export class RouteGuider extends THREE.EventDispatcher{
     }
     
     
-    updateArrowDisplay(){//根据当前位置更新显示一定范围内的箭头'
+    updateArrowDisplay(){//根据当前位置更新显示一定范围内的箭头 
     
         if(this.scenePoints.length == 0)return
         
@@ -579,14 +574,14 @@ export class RouteGuider extends THREE.EventDispatcher{
             if(i<startIndex || i>startIndex+arrowsShowingCount)e.visible = false
             else e.visible = true
         }) */
-        
+         
         let cameraPos = viewer.scene.getActiveCamera().position
         this.arrows.children.forEach((e,i)=>{
             if(e.position.distanceTo(cameraPos) < arrowShowMinDis) e.visible = true
             else e.visible = false
         })
         
-        
+        viewer.dispatchEvent('content_changed') 
     }
     
     
@@ -628,6 +623,7 @@ export class RouteGuider extends THREE.EventDispatcher{
         this.sceneMeshGroup.traverse(e=>e.visible = false)  //包括sprite也要设置,防止update
         this.mapMeshGroup.visible = false
         viewer.mapViewer.dispatchEvent({'type':'content_changed'})
+        viewer.dispatchEvent('content_changed') 
     }
     
     clear(){//退出

+ 19 - 22
src/custom/modules/siteModel/BuildingBox.js

@@ -168,7 +168,7 @@ export class BuildingBox extends ctrlPolygon{//建筑实体,包括building, fl
                 this.lineMesh.name = 'buildingLines'
                 this.lineMesh.visible = false            
                 this.add(this.lineMesh) 
-                viewer.setObjectLayers(this.lineMesh, 'bothMapAndScene' ) 
+                Potree.Utils.setObjectLayers(this.lineMesh, 'bothMapAndScene' ) 
             }
             
             
@@ -190,11 +190,8 @@ export class BuildingBox extends ctrlPolygon{//建筑实体,包括building, fl
         }else{
             if(prop.points){
                 this.points = prop.points  
-            }
-            
-            
-        }
-        
+            }  
+        } 
     } 
     
     intersectPointcloudVolume(pointcloud){//和pointcloud的重叠体积
@@ -342,9 +339,9 @@ export class BuildingBox extends ctrlPolygon{//建筑实体,包括building, fl
         var mesh = new THREE.Mesh(geometry, this.mats.boxDefault)
         mesh.name = 'buildingBox';
         if(this.buildType == 'floor'){
-            viewer.setObjectLayers(mesh, 'siteModelMapUnvisi' ) //楼层默认在地图不显示,为了不会叠加透明度
+            Potree.Utils.setObjectLayers(mesh, 'siteModelMapUnvisi' ) //楼层默认在地图不显示,为了不会叠加透明度
         }else{
-            viewer.setObjectLayers(mesh, 'bothMapAndScene' )
+            Potree.Utils.setObjectLayers(mesh, 'bothMapAndScene' )
         }
          
         
@@ -361,12 +358,12 @@ export class BuildingBox extends ctrlPolygon{//建筑实体,包括building, fl
         let marker = new Sprite({mat:this.getMarkerMaterial('default'), renderOrder : 3, sizeInfo: markerSizeInfo, dontFixOrient: true, name:"building_marker"} )
        
          
-        viewer.setObjectLayers(marker, 'siteModeOnlyMapVisi' ) 
+        Potree.Utils.setObjectLayers(marker, 'siteModeOnlyMapVisi' ) 
         
         o.marker = marker
         super.addMarker(o)
         
-        if(!this.selected)viewer.updateVisible(marker,'select',false) 
+        if(!this.selected)Potree.Utils.updateVisible(marker,'select',false) 
          
         let addClickEvent = (e)=>{ 
             let click = (e) => {   
@@ -410,7 +407,7 @@ export class BuildingBox extends ctrlPolygon{//建筑实体,包括building, fl
         
         marker.renderOrder = 3 
          
-        viewer.setObjectLayers(marker, 'siteModeOnlyMapVisi' ) 
+        Potree.Utils.setObjectLayers(marker, 'siteModeOnlyMapVisi' ) 
         { // Event Listeners  
             let mouseover = (e) => {
                 this.setMarkerSelected(e.object, 'hover', 'single'); 
@@ -439,7 +436,7 @@ export class BuildingBox extends ctrlPolygon{//建筑实体,包括building, fl
         }
         this.add(marker)
         this.updateMarker(marker, point)
-        if(!this.selected)viewer.updateVisible(marker,'select',false) 
+        if(!this.selected)Potree.Utils.updateVisible(marker,'select',false) 
         return marker
     }
     
@@ -773,12 +770,12 @@ export class BuildingBox extends ctrlPolygon{//建筑实体,包括building, fl
             })
               
             if(this.buildType == 'floor'){
-                viewer.setObjectLayers(this.box, 'bothMapAndScene' ) 
-                viewer.setObjectLayers(this.buildParent.box, 'siteModelMapUnvisi' ) //当选中floor或room时,building在地图不可见
+                Potree.Utils.setObjectLayers(this.box, 'bothMapAndScene' ) 
+                Potree.Utils.setObjectLayers(this.buildParent.box, 'siteModelMapUnvisi' ) //当选中floor或room时,building在地图不可见
             }
         }else if(this.buildType == 'room'){
-            viewer.setObjectLayers(this.buildParent.box, 'bothMapAndScene' )
-            viewer.setObjectLayers(this.buildParent.buildParent.box, 'siteModelMapUnvisi' )
+            Potree.Utils.setObjectLayers(this.buildParent.box, 'bothMapAndScene' )
+            Potree.Utils.setObjectLayers(this.buildParent.buildParent.box, 'siteModelMapUnvisi' )
         }
         
         
@@ -786,7 +783,7 @@ export class BuildingBox extends ctrlPolygon{//建筑实体,包括building, fl
         
         
         this.lineMesh.visible = true
-        this.markers && this.markers.forEach(e=>viewer.updateVisible(e,'select',true) )
+        this.markers && this.markers.forEach(e=>Potree.Utils.updateVisible(e,'select',true) )
         this.midMarkers && this.midMarkers.forEach(e=>e.visible = true)
         
         let holes = this.holes.concat(this.parentHoles)
@@ -810,17 +807,17 @@ export class BuildingBox extends ctrlPolygon{//建筑实体,包括building, fl
             })  
             
             if(this.buildType == 'floor'){
-                viewer.setObjectLayers(this.box, 'siteModelMapUnvisi' ) 
-                viewer.setObjectLayers(this.buildParent.box, 'bothMapAndScene' ) 
+                Potree.Utils.setObjectLayers(this.box, 'siteModelMapUnvisi' ) 
+                Potree.Utils.setObjectLayers(this.buildParent.box, 'bothMapAndScene' ) 
             }
             
         }else if(this.buildType == 'room'){
-            viewer.setObjectLayers(this.buildParent.box, 'siteModelMapUnvisi' )
-            viewer.setObjectLayers(this.buildParent.buildParent.box, 'bothMapAndScene' )
+            Potree.Utils.setObjectLayers(this.buildParent.box, 'siteModelMapUnvisi' )
+            Potree.Utils.setObjectLayers(this.buildParent.buildParent.box, 'bothMapAndScene' )
         }
         
         this.lineMesh.visible = false
-        this.markers && this.markers.forEach(e=>viewer.updateVisible(e,'select',false) )
+        this.markers && this.markers.forEach(e=>Potree.Utils.updateVisible(e,'select',false) )
         this.midMarkers && this.midMarkers.forEach(e=>e.visible = false)
         
         let holes = this.holes.concat(this.parentHoles)

+ 36 - 14
src/custom/modules/siteModel/SiteModel.js

@@ -91,9 +91,27 @@ var SiteModel = {
         }
         
         
+        {
+            let updated = false
+            this.bus.addEventListener('updated',()=>{ 
+                updated = true
+                Common.intervalTool.isWaiting('siteModelUpdated', ()=>{ 
+                    if(updated){
+                        updated = false
+                        this.changedCallback() 
+                        return true
+                    }
+                },500)
+            })
+        }
     }, 
     
-    
+    changedCallback(){
+        this.findPanos()
+        this.findEntityForDataset()
+        this.updateEntityAt(true) //更新所在建筑,更新marker显示
+        //console.log('changedCallback')
+    },
     
     updateEntityAt(force){
         //if(!this.entities.length || this.editing) return //编辑时也要根据位置显示不同楼层的漫游点与cad
@@ -166,7 +184,7 @@ var SiteModel = {
         
         
         viewer.images360.panos.forEach(pano=>{
-            viewer.setObjectLayers(pano.marker, 'siteModelMapUnvisi' ) 
+            Potree.Utils.setObjectLayers(pano.marker, 'siteModelMapUnvisi' ) 
         }) 
         mapViewport.layersAdd('siteModeOnlyMapVisi') //只有mapViewport能看到marker
        
@@ -193,7 +211,7 @@ var SiteModel = {
         })
 
         viewer.images360.panos.forEach(pano=>{
-            viewer.setObjectLayers(pano.marker, 'sceneObjects' ) 
+            Potree.Utils.setObjectLayers(pano.marker, 'sceneObjects' ) 
         })
         
         mapViewport.layersRemove('siteModeOnlyMapVisi') 
@@ -250,7 +268,7 @@ var SiteModel = {
             parent.unselect()  
             parent.select()    
         }
- 
+        this.bus.dispatchEvent('updated')
         return floor
     },
      
@@ -365,9 +383,9 @@ var SiteModel = {
                 //重新开始画
                 entity.reDraw(1)
                  
-                viewer.updateVisible(entity.markers[0],'unMove',false);
+                Potree.Utils.updateVisible(entity.markers[0],'unMove',false);
                 var f = ()=>{
-                    viewer.updateVisible(entity.markers[0],'unMove',true); 
+                    Potree.Utils.updateVisible(entity.markers[0],'unMove',true); 
                     entity.removeEventListener('dragChange',f)
                 }
                 entity.addEventListener('dragChange',f) 
@@ -424,9 +442,9 @@ var SiteModel = {
         
         
         var marker = entity.addMarker({point:new THREE.Vector3(0, 0, 0)})
-        viewer.updateVisible(marker,'unMove',false);//这时候的位置是假的(0,0,0)所以先不可见
+        Potree.Utils.updateVisible(marker,'unMove',false);//这时候的位置是假的(0,0,0)所以先不可见
         var f = ()=>{
-            viewer.updateVisible(marker,'unMove',true); 
+            Potree.Utils.updateVisible(marker,'unMove',true); 
             entity.removeEventListener('dragChange',f)
         }
         entity.addEventListener('dragChange',f)  
@@ -659,7 +677,11 @@ var SiteModel = {
             
         }
         //console.log('添加实体:', entity.buildType, entity.sid, entity.uuid)
-    
+        this.bus.dispatchEvent('updated')
+        entity.addEventListener('marker_dropped',()=>{
+            this.bus.dispatchEvent('updated')
+        })  
+        
     },
     
     removeEntity : function(entity){
@@ -700,14 +722,13 @@ var SiteModel = {
         let buildChildren = entity.buildChildren.slice()
         buildChildren.forEach(e=>this.removeEntity(e))
         
-         
+        this.bus.dispatchEvent('updated')
     },
     
     
-    updateBuildingZ:function(building){
-         
+    updateBuildingZ:function(building){ 
         building.buildChildren = building.buildChildren.sort((e,a)=>e.zMin-a.zMin)//从低到高排序
-        building.zMin = building.zMax = building.buildChildren[0].zMin  //基底高度 
+        building.buildChildren[0] && (building.zMin = building.zMax = building.buildChildren[0].zMin)  //基底高度 
         //building.zMax = building.buildChildren[building.buildChildren.length-1].zMax
         if(this.editing) building.update({dontUpdateChildren:true})
         building.dispatchEvent('updateBuildingZ')    
@@ -833,6 +854,7 @@ var SiteModel = {
         entity.dispatchEvent({type:'changeHeight'})
         //this.selected.emit('update')
         this.fitPullBox()
+        this.bus.dispatchEvent('updated')
     },
     
     
@@ -859,7 +881,7 @@ var SiteModel = {
         this.meshGroup.add(this.height_pull_box) 
         height_pull_box_up.position.set(0,0,1/2/* 3/8 */)
         height_pull_box_down.position.set(0,0,-1/2/* -3/8 */)
-        viewer.setObjectLayers(this.height_pull_box, 'siteModeSideVisi' )
+        Potree.Utils.setObjectLayers(this.height_pull_box, 'siteModeSideVisi' )
         
         
         

+ 29 - 24
src/custom/objects/Magnifier.js

@@ -9,11 +9,12 @@ const circleGeo = new THREE.CircleGeometry(1.45,100);
 const sphereGeo = new THREE.SphereBufferGeometry(0.018,10,10);
  
  
-const magDistance_ = 1;//相机离目标位置的距离的分界线,当离得远时要缩小fov以使看到的视野固定(望远镜效果)
+const magDisMin = 1;//相机离目标位置的距离的分界线,当离得远时要缩小fov以使看到的视野固定(望远镜效果)
+const magDisMax = 20
 /* const radius_ = 0.2; //当相机离目标位置的距离>magDistance_时,希望看到的视野的半径
-const maxFov = THREE.Math.radToDeg(Math.atan(radius_ / magDistance_ )) * 2//提前计算出当相机离目标位置的距离<magDistance_时的fov,均使用=magDistance_时的fov。只要保证该fov大于主相机的fov就会有放大效果 
+const maxFov = THREE.Math.radToDeg(Math.atan(radius_ / magDisMin )) * 2//提前计算出当相机离目标位置的距离<magDisMin时的fov,均使用=magDisMin时的fov。只要保证该fov大于主相机的fov就会有放大效果 
  */
-let w = 200/1.43;
+let w = 250/1.43;
 let maxPX = 1366*1024 //ipad pro.  大于这个分辨率的就直接用devicePixelRatio, 如macbook也是
 const width2dPX = Math.round(window.devicePixelRatio >= 2 ? ( window.screen.width * window.screen.height >= maxPX ? window.devicePixelRatio/1.2 : window.devicePixelRatio/1.5)*w : w)  //触屏或高分辨率的可能要放大些。但在手机上不能太大
 //console.log('width2dPX', width2dPX)
@@ -45,7 +46,7 @@ export default class Magnifier extends THREE.Object3D {//放大镜or望远镜
                 
                 viewer.scene.pointclouds.forEach(e=>{//因为更改pointDensity时会自动变opacity,所以这项最先获取
                     visiMap.set(e,e.visible)
-                    e.visible = viewer.getObjVisiByReason(e, 'datasetSelection'); //先将隐藏的点云显示
+                    e.visible = Potree.Utils.getObjVisiByReason(e, 'datasetSelection'); //先将隐藏的点云显示
                 
                     opacityBefore.set(e,e.temp.pointOpacity)  
                 }) 
@@ -134,7 +135,7 @@ export default class Magnifier extends THREE.Object3D {//放大镜or望远镜
         
         this.targetPoint.name = 'magnifierPointTarget'
         viewer.scene.scene.add(this.targetPoint)
-        viewer.setObjectLayers(this.targetPoint, 'magnifierContent' )
+        Potree.Utils.setObjectLayers(this.targetPoint, 'magnifierContent' )
         
         this.add(this.mesh)
         this.add(this.overlayMesh)
@@ -143,7 +144,7 @@ export default class Magnifier extends THREE.Object3D {//放大镜or望远镜
         this.mesh.renderOrder = 10;
         this.overlayMesh.renderOrder = 11;
         this.aimPos
-        viewer.setObjectLayers(this, 'magnifier' )
+        Potree.Utils.setObjectLayers(this, 'magnifier' )
         //viewer.inputHandler.addInputListener(this)
         
         
@@ -173,10 +174,10 @@ export default class Magnifier extends THREE.Object3D {//放大镜or望远镜
         
         var updateVisi = (e)=>{
             if(e.hoverViewport == viewer.mainViewport){
-                viewer.updateVisible(this,"atViewport", true)
+                Potree.Utils.updateVisible(this,"atViewport", true)
                 this.update(e.intersect && e.intersect.location)
             }else{
-                viewer.updateVisible(this,"atViewport", false) //小地图不显示
+                Potree.Utils.updateVisible(this,"atViewport", false) //小地图不显示
             } 
             
         }
@@ -194,7 +195,7 @@ export default class Magnifier extends THREE.Object3D {//放大镜or望远镜
          
          
         this.addEventListener("setEnable",(e)=>{
-            viewer.updateVisible(this, "enable", e.value) //界面开关
+            Potree.Utils.updateVisible(this, "enable", e.value) //界面开关
             /* if(Potree.settings.displayMode == 'showPanos') && e.value){
                 Potree.settings.pointDensity = 'magnifier'
             }else if() */
@@ -203,14 +204,14 @@ export default class Magnifier extends THREE.Object3D {//放大镜or望远镜
          
          
         if(Potree.settings.isOfficial){
-            viewer.updateVisible(this, "enable", false) 
+            Potree.Utils.updateVisible(this, "enable", false) 
         }else{
-            viewer.updateVisible(this, "measure", false) 
+            Potree.Utils.updateVisible(this, "measure", false) 
             viewer.addEventListener("measureMovePoint",()=>{//测量开始
-                viewer.updateVisible(this, "measure", true) 
+                Potree.Utils.updateVisible(this, "measure", true) 
             })
             viewer.addEventListener("endMeasureMove",()=>{
-                viewer.updateVisible(this, "measure", false) 
+                Potree.Utils.updateVisible(this, "measure", false) 
             })
         }
         
@@ -239,9 +240,11 @@ export default class Magnifier extends THREE.Object3D {//放大镜or望远镜
         var dis = playerPos.distanceTo(aimPos);
         var dirToCamera = new THREE.Vector3().subVectors(playerPos, aimPos ).normalize()
         
-        
+        const fareast = 300;  
         //相机位置
-        var finalDisToAim = dis>magDistance_ ? magDistance_ : dis / 2;
+        var finalDisToAim =  dis>magDisMin ? dis > fareast ? magDisMax : (dis-magDisMin) / (fareast-magDisMin) * (magDisMax-magDisMin) + magDisMin :  dis / 2;    //dis>magDistance_ ? magDistance_ : dis / 2;
+        
+        
         this.camera.position.copy(aimPos).add(dirToCamera.multiplyScalar(finalDisToAim))
         this.camera.lookAt(aimPos)
         this.camera.fov = playerCamera.fov / 2
@@ -258,7 +261,9 @@ export default class Magnifier extends THREE.Object3D {//放大镜or望远镜
         
         let newPos = new THREE.Vector3(screenPos.x,screenPos.y,0.8).unproject(playerCamera); //z:-1朝外       
         let dir = newPos.clone().sub(playerPos).normalize().multiplyScalar(10);//这个数值要大于playerCamera.near
-        let s = dis>magDistance_ ? 1 : dis / magDistance_  ;
+        let s =  finalDisToAim   // dis>magDisMin ? 1 : dis / magDisMin  ; 
+        
+        //let s = dis>magDisMin ? dis > fareast ? magDisMax : (dis-magDisMin) / (fareast-magDisMin) * (magDisMax-magDisMin) + magDisMin :  dis / magDisMin  
         
         this.position.copy(playerPos.clone().add(dir))
         this.quaternion.copy(playerCamera.quaternion); 
@@ -276,8 +281,8 @@ export default class Magnifier extends THREE.Object3D {//放大镜or望远镜
  
         if(!dontRender){
             this.waitRender = true
-        } 
-    
+        }  
+        viewer.dispatchEvent('content_changed')
     }
     
     
@@ -293,10 +298,10 @@ export default class Magnifier extends THREE.Object3D {//放大镜or望远镜
         var dis = playerPos.distanceTo(aimPos);
          
         
-        if(dis<magDistance_){
+        if(dis<magDisMin){
             this.camera.fov = maxFov
         }else{
-            this.camera.fov = THREE.Math.radToDeg(Math.atan(radius_ / dis )) * 2 //radius_是能看到的范围半径。当dis大于magDistance_时就放大,否则维持fov为maxFov
+            this.camera.fov = THREE.Math.radToDeg(Math.atan(radius_ / dis )) * 2 //radius_是能看到的范围半径。当dis大于magDisMin时就放大,否则维持fov为maxFov
         }
        
         this.camera.updateProjectionMatrix()
@@ -337,8 +342,8 @@ export default class Magnifier extends THREE.Object3D {//放大镜or望远镜
     
     render(){ 
  
-        if(!this.waitRender)return
-        //this.visible = false;//防止放大镜里有自己
+        if(!this.visible || !this.waitRender && !viewer.needRender)return  //viewer.needRender为true要渲染是因为可能是点云node加载完
+       
         viewer.render({
             target : this.renderTarget,
             viewports : [this.viewport],
@@ -348,9 +353,9 @@ export default class Magnifier extends THREE.Object3D {//放大镜or望远镜
             /* width :this.renderTarget.width,
             height: this.renderTarget.height, */
         })
-        //this.visible = true;
+      
         this.waitRender = false
-        
+        viewer.dispatchEvent('content_changed')
         
         
         

+ 20 - 14
src/custom/objects/Reticule.js

@@ -78,7 +78,7 @@ export default class Reticule extends THREE.Mesh{
         
          
         
-        viewer.setObjectLayers(this,  'sceneObjects' )
+        Potree.Utils.setObjectLayers(this,  'sceneObjects' )
     }
 
     judgeTex(){ 
@@ -114,30 +114,36 @@ export default class Reticule extends THREE.Mesh{
  
         
         this.hidden = !0 
-        transitions.start(lerp.property(this.material , "opacity", 0), duration)
-             
+        transitions.start(lerp.property(this.material , "opacity", 0, ()=>{//progress
+            viewer.dispatchEvent('content_changed')
+        }), duration,()=>{//done
+            this.dispatchEvent({type:'update', visible:false})
+        })  
+         
         this.dispatchEvent({type:'update', visible:false})
         
         setTimeout(()=>{
-            this.dispatchEvent({type:'update', visible:false})
+            
         },duration)
         
     }
 
     show(duration = 300){
          
-        if(!viewer.getObjVisiByReason(this, 'force'))return
+        if(!Potree.Utils.getObjVisiByReason(this, 'force'))return
         //console.log("show Reticule")
         this.hidden = !1
         
         if(this.material.opacity <= 0){
-            transitions.start(lerp.property(this.material, "opacity", defaultOpacity), duration)
+            transitions.start(lerp.property(this.material, "opacity", defaultOpacity, ()=>{//progress
+                viewer.dispatchEvent('content_changed')
+            }), duration,()=>{//done
+                this.dispatchEvent({type:'update', visible:false})
+            }) 
         
             this.dispatchEvent({type:'update', visible:true})
             
-            setTimeout(()=>{
-                this.dispatchEvent({type:'update', visible:false})
-            },duration)
+            
                 
         }
         
@@ -175,15 +181,15 @@ export default class Reticule extends THREE.Mesh{
     
         if(this.orthoPos && this.hoverViewport && this.hoverViewport.name == 'mapViewport' && viewport != this.hoverViewport){
             //若是在地图上更新,在其他viewport要隐藏。因为在地图上无法得知高度。     
-            viewer.updateVisible(this, 'hoverMap', false) 
+            Potree.Utils.updateVisible(this, 'hoverMap', false) 
             return; 
         } 
-        viewer.updateVisible(this, 'hoverMap', true)
+        Potree.Utils.updateVisible(this, 'hoverMap', true)
         
         if(viewport.name == 'mapViewport'){
-            viewer.setObjectLayers(this,  "bothMapAndScene")
+            Potree.Utils.setObjectLayers(this,  "bothMapAndScene")
         }else{//通常地图不显示reticule,只有在特殊编辑时才显示
-            viewer.setObjectLayers(this,  'sceneObjects') 
+            Potree.Utils.setObjectLayers(this,  'sceneObjects') 
         }
         
         
@@ -207,7 +213,7 @@ export default class Reticule extends THREE.Mesh{
 
     updatePosition(intersect, viewport ){ //在地图(当地图融合到viewer时)和场景里都显示且完全相同(大小可能不同)
          
-        if (viewer.getObjVisiByReason(this, 'force')) {//没有被强制隐藏,如进入某个页面后强制不显示
+        if (Potree.Utils.getObjVisiByReason(this, 'force')) {//没有被强制隐藏,如进入某个页面后强制不显示
             if (!intersect /* || !intersect.point.normal */){ 
                  return //this.hide();   
             }

+ 3 - 3
src/custom/objects/fireParticle/explode/ExplodeParticle.js

@@ -315,7 +315,7 @@ class ExplodeParticle extends THREE.Points {
     }
 
     update(dt) {
-        if(!viewer.getObjVisiByReason(this,'force')){//被手动隐藏了
+        if(!Potree.Utils.getObjVisiByReason(this,'force')){//被手动隐藏了
             return
         }
         if(this.delayStartTime>0){ // 爆炸延迟
@@ -325,10 +325,10 @@ class ExplodeParticle extends THREE.Points {
         
         
         if(!Potree.Utils.isInsideFrustum(this.boundingSphere, viewer.scene.getActiveCamera())){
-            viewer.updateVisible(this,'isInsideFrustum', false ) //不在视野范围
+            Potree.Utils.updateVisible(this,'isInsideFrustum', false ) //不在视野范围
             return
         }else{
-            viewer.updateVisible(this,'isInsideFrustum', true )
+            Potree.Utils.updateVisible(this,'isInsideFrustum', true )
         }
         //const timeRatio = 0.5
         if(dt > 1){

+ 3 - 3
src/custom/objects/fireParticle/fire/FireParticle.js

@@ -249,15 +249,15 @@ class FireParticle extends THREE.Points{
     
     
     update(delta){
-        if(!viewer.getObjVisiByReason(this,'force')){//被手动隐藏了
+        if(!Potree.Utils.getObjVisiByReason(this,'force')){//被手动隐藏了
             return
         }
         if(!Potree.Utils.isInsideFrustum(this.boundingBox, viewer.scene.getActiveCamera())){
-            viewer.updateVisible(this,'isInsideFrustum', false ) //不在视野范围
+            Potree.Utils.updateVisible(this,'isInsideFrustum', false ) //不在视野范围
             //console.log('unvi')
             return
         }else{
-            viewer.updateVisible(this,'isInsideFrustum', true )
+            Potree.Utils.updateVisible(this,'isInsideFrustum', true )
         } 
         delta *= 1//更改速度
         

+ 3 - 3
src/custom/objects/fireParticle/smoke/SmokeParticle.js

@@ -400,15 +400,15 @@ export default class SmokeParticle extends THREE.Points{
     
 
     update(dt){
-        if(!viewer.getObjVisiByReason(this,'force')){//被手动隐藏了
+        if(!Potree.Utils.getObjVisiByReason(this,'force')){//被手动隐藏了
             return
         }
         if(!Potree.Utils.isInsideFrustum(this.boundingBox, viewer.scene.getActiveCamera())){
-            viewer.updateVisible(this,'isInsideFrustum', false ) //不在视野范围
+            Potree.Utils.updateVisible(this,'isInsideFrustum', false ) //不在视野范围
             //console.log('unvi')
             return
         }else{
-            viewer.updateVisible(this,'isInsideFrustum', true )
+            Potree.Utils.updateVisible(this,'isInsideFrustum', true )
         } 
         
         

+ 1 - 1
src/custom/objects/tool/CurveCtrl.js

@@ -133,7 +133,7 @@ export default class CurveCtrl extends THREE.Object3D {
             points = []
         } 
         
-        
+         
         LineDraw.updateLine(this.line, points)      
         
         

+ 5 - 5
src/custom/objects/tool/Measure.js

@@ -99,7 +99,7 @@ export class Measure extends ctrlPolygon{
         this.selectStates = {}
         
         this.setUnitSystem(prop.unit || viewer.unitConvert.UnitService.defaultSystem)
-        viewer.setObjectLayers(this, 'measure' )
+        Potree.Utils.setObjectLayers(this, 'measure' )
         
         //addMarkers:
        
@@ -315,7 +315,7 @@ export class Measure extends ctrlPolygon{
 	addMarker (o={}) {
          
         let marker = new Sprite({mat:this.getMarkerMaterial('default'), sizeInfo: markerSizeInfo, name:"measure_point"} )
-        viewer.setObjectLayers(marker, 'measure' )
+        Potree.Utils.setObjectLayers(marker, 'measure' )
         marker.pickOrder = marker.renderOrder = 3 
         marker.markerSelectStates = {} 
         marker.addEventListener('startDragging',(e)=>{
@@ -329,7 +329,7 @@ export class Measure extends ctrlPolygon{
 		{ // edges 
             edge = LineDraw.createFatLine( [ ],{material:this.getLineMat('edgeDefault')} ) 
             edge.pickOrder = 0
-            viewer.setObjectLayers(edge, 'measure' ) 
+            Potree.Utils.setObjectLayers(edge, 'measure' ) 
 
 
                         
@@ -658,7 +658,7 @@ export class Measure extends ctrlPolygon{
         }
         edgeLabel.visible = false
         edgeLabel.sprite.material.depthTestWhenPick = true
-        viewer.setObjectLayers(edgeLabel, 'measure' )
+        Potree.Utils.setObjectLayers(edgeLabel, 'measure' )
         this.add(edgeLabel)
         return edgeLabel
     }
@@ -689,7 +689,7 @@ export class Measure extends ctrlPolygon{
         areaLabel.addEventListener('click',()=>{
             this.isNew || viewer.focusOnObject(this, 'measure')
         })
-        viewer.setObjectLayers(areaLabel, 'measure' )
+        Potree.Utils.setObjectLayers(areaLabel, 'measure' )
         areaLabel.visible = false
         
         return areaLabel;

+ 1 - 1
src/custom/objects/tool/MeasuringTool.js

@@ -609,7 +609,7 @@ export class MeasuringTool extends THREE.EventDispatcher{
 	render(o={}){
         if(this.scene.children.length == 0)return
         
-        viewer.setCameraLayers(o.camera, ['measure'])
+        Potree.Utils.setCameraLayers(o.camera, ['measure'])
 		
         if(o.screenshot && this.viewer.ssaaRenderPass.enabled){ //抗锯齿
             this.viewer.ssaaRenderPass.sampleLevel = 4

+ 17 - 13
src/custom/objects/tool/TransformControls.js

@@ -97,7 +97,7 @@ var TransformControls = function ( camera, domElement, options ) {
 	var worldQuaternionInv = new THREE.Quaternion();
 	var worldScale = new THREE.Vector3();
 
-	var eye = new THREE.Vector3();
+	var eye = new THREE.Vector3(); 
 
 	var positionStart = new THREE.Vector3();
 	var quaternionStart = new THREE.Quaternion();
@@ -176,7 +176,7 @@ var TransformControls = function ( camera, domElement, options ) {
 		this.visible = true;
 		//Config.keyCon = false;//add
         //this.linesAssistance.setVisible(true)
-        
+        viewer.dispatchEvent('content_changed') 
 		return this;
 
 	};
@@ -190,7 +190,7 @@ var TransformControls = function ( camera, domElement, options ) {
 		//Config.keyCon = true;//add
         
         //this.linesAssistance.setVisible(false)
-        
+        viewer.dispatchEvent('content_changed') 
 		return this;
 
 	};
@@ -296,14 +296,14 @@ var TransformControls = function ( camera, domElement, options ) {
 
         //if(this.dragging === true /* || ( pointer.button !== undefined && pointer.button !== 0 )  */) return;
 
-
+         
         if(!this.dragging){
-
+            let oldAxis = this.axis
             //ray.setFromCamera( pointer, this.camera ); //这句会在floorplan模式get不到intersect
             let {origin, direction} = viewer.inputHandler.getMouseDirection()  
             ray.set(origin,  direction);
             
-            viewer.setCameraLayers(ray,   //设置能识别到的layers 
+            Potree.Utils.setCameraLayers(ray,   //设置能识别到的layers 
                 ['sceneObjects','mapObjects','measure',  'transformationTool', 'model'],
                 viewer.inputHandler.hoverViewport && viewer.inputHandler.hoverViewport.extraEnableLayers
             )
@@ -320,6 +320,9 @@ var TransformControls = function ( camera, domElement, options ) {
                 this.axis = null;
 
             }
+            if(oldAxis != this.axis){
+                viewer.dispatchEvent('content_changed') 
+            }
         }else{
             //this.pointerMove() 
             
@@ -336,7 +339,7 @@ var TransformControls = function ( camera, domElement, options ) {
 			let {origin, direction} = viewer.inputHandler.getMouseDirection()  
             ray.set(origin,  direction);
             
-            viewer.setCameraLayers(ray,   //设置能识别到的layers 
+            Potree.Utils.setCameraLayers(ray,   //设置能识别到的layers 
                 ['sceneObjects','mapObjects','measure',  'transformationTool', 'model'],
                 viewer.inputHandler.hoverViewport && viewer.inputHandler.hoverViewport.extraEnableLayers
             )
@@ -421,7 +424,7 @@ var TransformControls = function ( camera, domElement, options ) {
         let {origin, direction} = viewer.inputHandler.getMouseDirection()  
 		ray.set(origin,  direction);
 
-        viewer.setCameraLayers(ray,   //设置能识别到的layers 
+        Potree.Utils.setCameraLayers(ray,   //设置能识别到的layers 
             ['sceneObjects','mapObjects','measure',  'transformationTool', 'model'],
             viewer.inputHandler.hoverViewport && viewer.inputHandler.hoverViewport.extraEnableLayers
         )
@@ -755,13 +758,13 @@ var TransformControls = function ( camera, domElement, options ) {
             object.dispatchEvent({
                 type: "rotation_changed" 
             });
-          
+            
             
 		}
 
 		this.dispatchEvent( changeEvent );
 		this.dispatchEvent( objectChangeEvent );
-
+        viewer.dispatchEvent('content_changed') 
 	};
 
 	this.pointerUp = function ( pointer ) {
@@ -781,6 +784,7 @@ var TransformControls = function ( camera, domElement, options ) {
             this.rotateStart = null//add
             this.dispatchEvent({type:'transform_end'})
             
+
 		}
 
 		this.dragging = false;
@@ -1390,7 +1394,7 @@ var TransformControlsGizmo = function (options) {
 			var handle = handles[ i ];
             //add
             if(this.hideAxis[this.mode] && this.hideAxis[this.mode].some(e=>handle.name.includes(e.toUpperCase()))){
-                viewer.updateVisible(handle, 'hidden', false)
+                Potree.Utils.updateVisible(handle, 'hidden', false)
                 continue 
             }   
             
@@ -1520,7 +1524,7 @@ var TransformControlsGizmo = function (options) {
 				}
 
 				// If updating helper, skip rest of the loop
-                viewer.updateVisible(handle, 'hidden', !!visible)
+                Potree.Utils.updateVisible(handle, 'hidden', !!visible)
 				continue;
 
 			}
@@ -1715,7 +1719,7 @@ var TransformControlsGizmo = function (options) {
 			visible = visible && ( handle.name.indexOf( "Z" ) === - 1 || this.showZ );
 			visible = visible && ( handle.name.indexOf( "E" ) === - 1 || ( this.showX && this.showY && this.showZ ) );
             
-            viewer.updateVisible(handle, 'hidden', !!visible)
+            Potree.Utils.updateVisible(handle, 'hidden', !!visible)
             
             
             

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

@@ -84,7 +84,7 @@ export class mapClipBox extends ctrlPolygon {
         
         
         
-        viewer.setObjectLayers(this, 'mapObjects' )
+        Potree.Utils.setObjectLayers(this, 'mapObjects' )
     }
    
    

+ 222 - 26
src/custom/potree.shim.js

@@ -147,7 +147,7 @@ var texLoader = new THREE.TextureLoader()
                 }
             }
 
-            return  gl.getExtension('EXT_frag_depth'); //shader中的GL_EXT_frag_depth需要判断一下detectIOS吗。。
+            return gl instanceof WebGL2RenderingContext || gl.getExtension('EXT_frag_depth'); //shader中的GL_EXT_frag_depth需要判断一下detectIOS吗。。
         }
     } 
     
@@ -217,12 +217,25 @@ Utils.loadSkybox = function(path, oldSky ) {
     return {camera, scene, parent, cameraOrtho};
 };
 
+
+
+  
+
 Utils.getMousePointCloudIntersection = function(viewport, mouse, pointer, camera, viewer, pointclouds, pickParams = {} ) {
+    //getIntersectByDepthTex
+    /* let result = viewer.edlRenderer.depthTexSampler.sample(viewport, mouse)//add
+    if(result != 'unsupport')return result
+      */
+    
+    
+    
     if(!pointclouds || pointclouds.length == 0)return
     //console.log('getMousePointCloudIntersection')
     let renderer = viewer.renderer;
     
-      
+    
+    
+    
     if(viewport){ //转换到类似整个画面时
         /*let mouseInViewport = Utils.convertNDCToScreenPosition(pointer, null, viewport.resolution.x, viewport.resolution.y)
         pickParams.x = mouseInViewport.x   //mouse.x / viewport.width;
@@ -271,7 +284,7 @@ Utils.getMousePointCloudIntersection = function(viewport, mouse, pointer, camera
         
         pointclouds.forEach(e=>{//因为全景模式的pointSizeType是fixed所以要还原下
             visiMap.set(e,e.visible)
-            e.visible = viewer.getObjVisiByReason(e, 'datasetSelection'); //先将隐藏的点云显示
+            e.visible = Potree.Utils.getObjVisiByReason(e, 'datasetSelection'); //先将隐藏的点云显示
             if(!e.visible)return
             size.set(e, e.temp.pointSize)    
             sizeType = e.material.pointSizeType  
@@ -466,8 +479,11 @@ Utils.screenPass = new function () {
 		if (typeof target === 'undefined') {
 			renderer.render(this.screenScene, this.camera);
 		} else {
+            let oldTarget = renderer.getRenderTarget()
             renderer.setRenderTarget(target)
+            renderer.clear()
 			renderer.render(this.screenScene, this.camera);
+            renderer.setRenderTarget(oldTarget)  
 		}
 	};
 }();
@@ -720,7 +736,139 @@ Utils.getIntersect = function (camera, meshes, pointer, raycaster) {
     return n[0]
 } 
 
-BinaryLoader.prototype.load = function(node){//解析点云
+
+
+
+Utils.addOrRemoveDefine = function(material, defineName, type, value=''){ 
+    let defines = material.defines
+    if(type == 'add'){
+        if(defines[defineName] != void 0 && defines[defineName] == value)return
+        defines[defineName] = value
+    }else{
+        if(defines[defineName] != void 0)return;
+        delete defines[defineName] 
+    }
+    material.needsUpdate = true;
+} 
+
+Utils.makeTexDontResize = function(map){//避免贴图因非2的次方而缩小。小心使用
+    if(!map || !map.image){  
+        return console.log('!map || !map.image', map, map&&map.image)
+    } 
+    if(THREE.Math.isPowerOfTwo(map.image.width ) && THREE.Math.isPowerOfTwo(map.image.height ))return
+    map.wrapS = map.wrapT = THREE.ClampToEdgeWrapping; //原默认 RepeatWrapping 
+    map.minFilter = THREE.LinearFilter; // or THREE.NearestFilter  原默认 LinearMipmapLinearFilter
+    map.needsUpdate = true
+} 
+
+
+Utils.updateVisible = function(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() 
+    
+} 
+ 
+ 
+ 
+ 
+Utils.getObjVisiByReason = function(object,reason){//获取在某条件下是否可见.  注: 用户在数据集选择可不可见为"datasetSelection"
+    if(object.visible)return true
+    else{
+        return !object.unvisibleReasons || !object.unvisibleReasons.some(e=>e.reason == reason)  
+    }
+} 
+ 
+
+
+Utils.setCameraLayers = function(camera, enableLayers, extraEnableLayers=[]){//add
+    camera.layers.disableAll() 
+    enableLayers.concat(extraEnableLayers).forEach(e=>{
+        let layer = Potree.config.renderLayers[e]
+        if(layer == void 0){
+            console.error('setCameraLayer没找到layer!');
+            return 
+        }
+        camera.layers.enable(layer)
+    })
+}
+Utils.setObjectLayers = function(object, layerName){//add
+    let layer = Potree.config.renderLayers[layerName]
+    if(layer == void 0){
+        console.error('setCameraLayer没找到layer!');
+        return 
+    }
+    object.traverse(e=>{ 
+        e.layers.set(layer)
+    })
+}
+
+
+
+
+
+
+
+
+
+
+
+BinaryLoader.prototype.load = function(node, callback){//解析点云
     if (node.loaded) {
         return;
     }
@@ -740,7 +888,7 @@ BinaryLoader.prototype.load = function(node){//解析点云
         if (xhr.readyState === 4) {
             if((xhr.status === 200 || xhr.status === 0) &&  xhr.response !== null){
                 let buffer = xhr.response;
-                this.parse(node, buffer);
+                this.parse(node, buffer, callback); 
             } else {
                 //console.error(`Failed to load file! HTTP status: ${xhr.status}, file: ${url}`);
                 throw new Error(`Failed to load file! HTTP status: ${xhr.status}, file: ${url}`);
@@ -838,8 +986,8 @@ Potree.updatePointClouds =  function(pointclouds,camera, areaSize  ){
 
  
 Potree.updateVisibilityStructures = function(pointclouds, camera, areaSize) {
-	let frustums = [];
-	let camObjPositions = [];
+	let frustums = {};
+	let camObjPositions = {}
 	let priorityQueue = new BinaryHeap(function (x) { return 1 / x.weight; });//二叉堆。
 
 	for (let i = 0; i < pointclouds.length; i++) {
@@ -848,13 +996,28 @@ Potree.updateVisibilityStructures = function(pointclouds, camera, areaSize) {
 		if (!pointcloud.initialized()) {
 			continue;
 		}
-
+        
+        
 		pointcloud.numVisibleNodes = 0;
 		pointcloud.numVisiblePoints = 0;
 		pointcloud.deepestVisibleLevel = 0;
 		pointcloud.visibleNodes = [];
 		pointcloud.visibleGeometry = [];
 
+
+        // 因漫游模式而隐藏的话 依旧需要加入visibleNodes,因为pick需要
+        /* if (pointcloud.visible && pointcloud.root !== null) {
+			priorityQueue.push({pointcloud: i, node: pointcloud.root, weight: Number.MAX_VALUE});
+		}  */                                   
+		if (pointcloud.visible || !pointcloud.hasDepthTex && pointcloud.unvisibleReasons && pointcloud.unvisibleReasons.length == 1 && pointcloud.unvisibleReasons[0].reason == 'displayMode'   &&  pointcloud.root !== null) {//改 visible -> 
+            priorityQueue.push({pointcloud: i, node: pointcloud.root, weight: Number.MAX_VALUE});
+		}else{
+            continue
+        }            
+        
+        
+        
+        
 		// frustum in object space
 		camera.updateMatrixWorld();
 		let frustum = new THREE.Frustum();
@@ -870,22 +1033,16 @@ Potree.updateVisibilityStructures = function(pointclouds, camera, areaSize) {
 
 		let fm = new THREE.Matrix4().multiply(proj).multiply(viewI).multiply(world);
 		frustum.setFromProjectionMatrix(fm);
-		frustums.push(frustum);
+		frustums[i] = frustum  //frustums.push(frustum);
 
 		// camera position in object space
 		let view = camera.matrixWorld;
 		let worldI = world.clone().invert();
 		let camMatrixObject = new THREE.Matrix4().multiply(worldI).multiply(view);
 		let camObjPos = new THREE.Vector3().setFromMatrixPosition(camMatrixObject);
-		camObjPositions.push(camObjPos);
+		camObjPositions[i] = camObjPos//camObjPositions.push(camObjPos);
+        
         
-        // 因漫游模式而隐藏的话 依旧需要加入visibleNodes,因为pick需要
-        /* if (pointcloud.visible && pointcloud.root !== null) {
-			priorityQueue.push({pointcloud: i, node: pointcloud.root, weight: Number.MAX_VALUE});
-		}  */                                   
-		if (pointcloud.visible || !pointcloud.hasDepthTex && pointcloud.unvisibleReasons && pointcloud.unvisibleReasons.length == 1 && pointcloud.unvisibleReasons[0].reason == 'displayMode'   &&  pointcloud.root !== null) {//改 visible -> 
-			priorityQueue.push({pointcloud: i, node: pointcloud.root, weight: Number.MAX_VALUE});
-		} 
 
 		// hide all previously visible nodes
 		// if(pointcloud.root instanceof PointCloudOctreeNode){
@@ -944,7 +1101,7 @@ Potree.updateVisibility = function(pointclouds, camera, areaSize){
 	let pointcloudTransformVersion = Potree._pointcloudTransformVersion;
 	for(let pointcloud of pointclouds){
 
-		if(pointcloud.hasDepthTex ? !pointcloud.visible : !viewer.getObjVisiByReason(pointcloud, 'datasetSelection')){//改 visible ->  
+		if(pointcloud.hasDepthTex ? !pointcloud.visible : !Potree.Utils.getObjVisiByReason(pointcloud, 'datasetSelection')){//改 visible ->  
 			continue;
 		} 
         
@@ -986,7 +1143,7 @@ Potree.updateVisibility = function(pointclouds, camera, areaSize){
 		let box = node.getBoundingBox();
 		let frustum = frustums[element.pointcloud];
 		let camObjPos = camObjPositions[element.pointcloud];
-
+        if(!frustum) continue //add
 		let insideFrustum = frustum.intersectsBox(box);
 		let maxLevel = pointcloud.maxLevel == void 0 ? Infinity : pointcloud.maxLevel;
 		let level = node.getLevel();
@@ -1236,10 +1393,34 @@ Potree.updateVisibility = function(pointclouds, camera, areaSize){
 			pointcloud.dem.update(updatingNodes);
 		}
 	}
-    //加载点云
-	for (let i = 0; i < Math.min(Potree.maxNodesLoading, unloadedGeometry.length); i++) {
-		unloadedGeometry[i].node.load(unloadedGeometry[i].pointcloud.pcoGeometry); 
-	}
+    
+    
+    
+    
+    if(unloadedGeometry.length){//加载点云 
+         
+        /* for (let i = 0; i < Math.min(Potree.maxNodesLoading, unloadedGeometry.length); i++) {
+            unloadedGeometry[i].node.load(unloadedGeometry[i].pointcloud.pcoGeometry); 
+        }  */ 
+     
+        let timeStamp = performance.getEntriesByName("loop-start");
+        let maxNodesLoading
+        if(timeStamp.length){
+            let dur = performance.now() - timeStamp[timeStamp.length-1].startTime;
+            maxNodesLoading = THREE.Math.clamp(Math.round(9 - dur), 1, 6 )   //dur在iphoneX中静止有7,pc是2
+            //console.log('maxNodesLoading',maxNodesLoading, dur)
+        }else{
+            maxNodesLoading = 6
+        } 
+        
+        //主要在手机端有效果。不改之前在展示的点云较多时前进会卡。
+        for (let i = 0; i < Math.min(maxNodesLoading, unloadedGeometry.length); i++) {
+            unloadedGeometry[i].node.load(unloadedGeometry[i].pointcloud.pcoGeometry); 
+        }   
+    }
+    
+    
+    
     
     //add:
     Potree.numVisiblePoints = numVisiblePoints
@@ -1651,6 +1832,17 @@ PointCloudOctreeGeometryNode.prototype.loadHierachyThenPoints = function(pointcl
         } 
     }
 } 
+PointCloudOctreeGeometryNode.prototype.loadPoints = function(){
+    let name = this.name
+    this.pcoGeometry.loader.load(this, ()=>{//callback
+        viewer.dispatchEvent('pointcloud_changed')  
+         
+        
+        //console.log('loadPoints success   ', name) 
+    });
+} 
+//加载点云成功->准备渲染画面->更新点云可见性updateVisibility->请求加载新的点云
+
  
 PointCloudOctreeGeometryNode.prototype.traverse = function(t, e){//add from navvis 25.js
     void 0 === e && (e = !0);
@@ -1663,14 +1855,17 @@ PointCloudOctreeGeometryNode.prototype.traverse = function(t, e){//add from navv
     }
 }
 
-Object.assign( PointCloudOctreeGeometry.prototype, THREE.EventDispatcher.prototype );
+Object.assign( PointCloudOctreeGeometry.prototype, THREE.EventDispatcher.prototype  );
+
+
+
 
 LRU.prototype.freeMemory = function(){
     
     if (this.elements <= 1) {
         return;
     } 
-    let memoryRatio = browser.isMobile ? 2 : 3;
+    let memoryRatio = browser.isMobile ? 2 : 5;
     //改成navvis的,使用pointBudget,否则四屏点云闪烁。 (似乎要比updateVisiblede的node时限制要宽些,作为缓存继续存着。否则会闪烁)
     let max =  viewer.viewports.length * memoryRatio * Potree.pointBudget 
        
@@ -1698,7 +1893,7 @@ VolumeTool.prototype.update = function(){}
 VolumeTool.prototype.startInsertion = function(args = {}){
     
     let volume; 
-    let camera = this.viewer.scene.getActiveCamera();
+    
     if(args.type){
         volume = new args.type();
     }else{
@@ -1718,6 +1913,7 @@ VolumeTool.prototype.startInsertion = function(args = {}){
     
     
     let updatePose = ()=>{ //保证在视野中的大小一致: 
+        let camera = this.viewer.scene.getActiveCamera();
         let w = math.getScaleForConstantSize({
             width2d: 300,
             camera , position:volume.getWorldPosition(new THREE.Vector3()) ,

+ 26 - 39
src/custom/settings.js

@@ -74,13 +74,7 @@ const config = {//配置参数   不可修改
         prefix6: 'https://mix3d.4dkankan.com/backend',
         
     },
-     
-    /* transitionsTime:{
-        flyTime : 1000  // 毫秒/米
-        panoToPano: 1000, 
-        flyIn:1000,
-        flyOut:1000,
-    } */
+    
     transitionsTime:{
         flyMinTime : 500 /* * 3 */,  // 毫秒/米
         flytimeDistanceMultiplier: 150/* * 3  */,
@@ -127,7 +121,7 @@ const config = {//配置参数   不可修改
         ,
         panoEdit:{
             maxLevelPercent: 1,  //在远处时由于pointBudget限制而展示稀疏,凑近时就变为最高质量了
-            pointBudget :4*1000*1000, //避免卡顿
+            pointBudget :6*1000*1000, //比最高的低一点,避免卡顿
             percentByUser:true,
             minNodeSize : 50,
         },
@@ -205,8 +199,7 @@ const config = {//配置参数   不可修改
         
         //sizeAddAtPanoRtEDL : 0.5, //全景模式静止时的size
         //ADAPTIVE : 字会失真扭曲
-        //'ATTENUATED' 往旁边看有缝隙、点在浮动
-        //navvis的shader在哪里 为什么不会抖动
+        //'ATTENUATED' 往旁边看有缝隙、点在浮动 
     }
     ,
     skyboxBgWidth : 100 , 
@@ -267,10 +260,10 @@ const config = {//配置参数   不可修改
         maxNavPanoQuality: browser.valueFromHash("maxtileq", null),
         maxZoomPanoQuality: browser.valueFromHash("maxztileq", null),
         overlayStyle: browser.valueFromHash("tileoverlay", 0),
-        uploadIntervalDelay: browser.valueFromHash("tileupdelay", 10),
+        uploadIntervalDelay: browser.valueFromHash("tileupdelay", 10 ),
         initialIntervalDelay: browser.valueFromHash("itiledelay", 0),
-        maxNonBaseUploadsPerFrame: browser.valueFromHash("maxnbtpf", 2),
-        maxBaseUploadsPerFrame: browser.valueFromHash("maxbtpf", 6),
+        maxNonBaseUploadsPerFrame: browser.valueFromHash("maxnbtpf", 1),
+        maxBaseUploadsPerFrame: browser.valueFromHash("maxbtpf",6),
         customCompression: browser.valueFromHash("tilecustcomp", 0),
         mobileHighQualityOverride: !1,
         allowUltraHighResolution: !0
@@ -294,7 +287,7 @@ const config = {//配置参数   不可修改
     clickMaxDragDis:5,
     clickMaxPressTime:500, //ms
     doubleClickTime:200,//双击间隔时间
-     
+    testNodeCount1: browser.isMobile() ? 6 : 3,  //testMaxNode次数达到这个数字时,changePointSize才使用nodeMaxLevel
      
     background: '#232323',
     mapBG:/* '#232323',   */  '#F5F5F5',   //地图的clearColor
@@ -319,27 +312,21 @@ const config = {//配置参数   不可修改
     },
 }
 
-
+ 
 config.OrthoCameraLimit = {
-    standard:{ 
-        zoom:{min:0.001, max:500}, //如果camera缩太小,地图会因为数字边界问题而扭曲
-        posBound:{ 
-            min: {x:-1e5, y:-1e5,z: config.map.cameraHeight},
-            max: {x:1e5, y:1e5, z:1 / 0  }
-        }  
+    standard:{  
+        zoom:{min:0.0004, max:500}, //如果camera缩太小,地图会因为数字边界问题而扭曲
+        latPad:20,
+        xBound:[-4e6, 4e6],  
     },
-    expand:{ //范围再大些,用于编辑空间模型等(但是万一中心点靠近地图边缘的话,就很容易扭曲了)
-        zoom:{min:0.0004, max:100}, //如果camera缩太小,地图会因为数字边界问题而扭曲
-        posBound:{ 
-            min: {x:-5000000, y:-1000000,z:config.map.cameraHeight},
-            max: {x:5000000, y:1000000, z:1 / 0  }
-        }//40075017
-    }
-    
+    expand:{  
+        zoom:{min:0.0004, max:500}, //如果camera缩太小,地图会因为数字边界问题而扭曲
+        latPad:20,
+        xBound:[-6e6, 6e6], 
+    }, 
 }
 
 
-
 /* 显示模式:
 
 1只显示点云: 滚轮为前进后退,方向键可以行走。进入漫游点时自动变为混合(这样全景可以弥补缝隙),过渡时只显示点云。
@@ -366,7 +353,7 @@ function getPrefix(){
     return v[0]
 }
 
- 
+let isTest = browser.urlHasValue('test')
 let settings = {//设置   可修改
     editType : '',
     number: '', //场景序号
@@ -377,7 +364,7 @@ let settings = {//设置   可修改
     isLocal:false, //是否本地 局域网版本
     libsUrl:'../libs/',
     displayMode:'',
-    isTest : browser.urlHasValue('test'),
+    isTest ,
     prefix: getPrefix(),
     pointDensity: '',    UserPointDensity:'',//pointDensity会随着进入不同的模块而自动改变,UserPointDensity记录了用户的设置
     UserDensityPercent:null,//点云密度百分比 
@@ -435,18 +422,18 @@ let settings = {//设置   可修改
     depTexLocBindDataset: true,//是否在pano模式下,使用深度图得到intersect的话,改intersect能属于该pano所在的点云。也就相当于在全景模式下intersect的点属于该全景图
 
     notAdditiveBlending:false, //点云是否使用普通的blend, 否则会曝光过渡
-    precision:2,  // 两位小数
-    
+    precision:2,  // 两位小数 
+    useV4url:true, //v4的全景图等路径不一样 scene_view_data
     
-    testV4url:true, //v4的全景图等路径不一样 scene_view_data
-    
-    
-    //testCube:true,
+    //testRT:true,  //似乎感觉不出差别
+    showCompass : isTest,
+    showAxis : isTest,
+    //testCube : true,
 }
   
  
 settings.isLocalhost = settings.prefix.includes('localhost')
 
- 
+console.log('2023-1')
  
 export {config, settings}

+ 54 - 8
src/custom/start.js

@@ -10,7 +10,7 @@ import './three.shim.js'
 import "./potree.shim.js"
 
  
- 
+
 export function start(dom, mapDom, number ){ //t-Zvd3w0m
     /* {
         let obj = JSON.parse(localStorage.getItem('setting'))
@@ -20,8 +20,9 @@ export function start(dom, mapDom, number ){ //t-Zvd3w0m
     }
      */ 
     Potree.settings.number = number || 't-o5YMR13'// 't-iksBApb'// 写在viewer前
-    
-    
+    //Potree.measureTimings = true //test
+    Potree.settings.mapCompany = browser.urlHasValue('google')? 'google' :  'default' /////////test
+
      
     
     let viewer = new Potree.Viewer(dom , mapDom);
@@ -127,6 +128,12 @@ export function start(dom, mapDom, number ){ //t-Zvd3w0m
         
         var transformPointcloud = (pointcloud, dataset)=>{
             var locationLonLat = dataset.location.slice(0,2)
+            
+            /* if(window.AMapWith84){//需要转换
+                locationLonLat = AMapWith84.wgs84ToAMap({x:locationLonLat[0], y:locationLonLat[1]})
+                locationLonLat = [locationLonLat.x,locationLonLat.y] 
+            } */
+           
             //当只有一个dataset时,无论如何transform 点云和漫游点都能对应上。
             var location = viewer.transform.lonlatToLocal.forward(locationLonLat)  //transform.inverse()
             //初始化位置 
@@ -154,20 +161,53 @@ export function start(dom, mapDom, number ){ //t-Zvd3w0m
         
         {//拿初始数据集作为基准。它的位置是000
             var locationLonLat = originDataset.location.slice(0,2)
-            proj4.defs("NAVVIS:TMERC", "+proj=tmerc +ellps=WGS84 +lon_0=" + locationLonLat[0].toPrecision(15) + " +lat_0=" + locationLonLat[1].toPrecision(15));
+            proj4.defs("LOCAL", "+proj=tmerc +ellps=WGS84 +lon_0=" + locationLonLat[0].toPrecision(15) + " +lat_0=" + locationLonLat[1].toPrecision(15)); //高德坐标系
+            proj4.defs("LOCAL_MAP", "+proj=tmerc +ellps=WGS84 +lon_0=" + locationLonLat[0].toPrecision(15) + " +lat_0=" + locationLonLat[1].toPrecision(15));
             proj4.defs("WGS84", "+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs");
              
-            let transform1 = proj4("WGS84", "NAVVIS:TMERC"); //这个ok  TMERC是展开的平面投影
+            let transform1 = proj4("WGS84", "LOCAL"); //这个ok 是展开的平面投影  LOCAL即NAVVIS:TMERC
             let transform2 = proj4("+proj=tmerc +lat_0=0 +lon_0=123 +k=1 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m +no_defs;");
-            
-            
+            //注:转入后再转出,和原来的有偏差。如果输入是local坐标,数字越大偏差越大,当百万时就明显了。如果是lonlat,很奇怪经度小于50时就乱了。
             viewer.transform = {
                 lonlatToLocal : transform1,
                 lonlatTo4550 : transform2       // 转大地坐标EPSG:4550  
             } 
             
+            if(window.AMapWith84 && Potree.settings.mapCompany != 'google'){//需要转换, 因本地高德用的lonlat和数据里的不一样,数据是84的
+                let change = (transform)=>{
+                    let forward = transform.forward
+                    let inverse = transform.inverse;
+                    
+                    transform.forward = function(e){
+                         let needTran = e.x == void 0
+                         if(needTran)e = {x:e[0],y:e[1]}
+                         var a = AMapWith84.wgs84ToAMap(e)
+                         needTran &&  (a = [a.x, a.y] )                        
+                         return  forward(a)
+                    }
+                    
+                    transform.inverse = function(e){
+                        let needTran = e.x == void 0
+                        var a = inverse(e)
+                        needTran && (a = {x:a[0],y:a[1]})
+                        a = AMapWith84.aMapToWgs84(a)  
+                        needTran && (a = [a.x,a.y])
+                        return a
+                        
+                    } 
+                     
+                }
+                for(let f in viewer.transform){
+                    change(viewer.transform[f]) 
+                }   
+            }
+            
+            
+            
             viewer.mapViewer && viewer.mapViewer.mapLayer.maps[0].updateProjection()
             
+            
+            
         }
          
         
@@ -411,7 +451,7 @@ export function panoEditStart(dom, number, fileServer){
        
         panoData.forEach((pano, index)=>{
             //let cloudPath = `${Potree.scriptPath}/data/panoEdit/uuidcloud/${pano.uuid}/cloud.js` 
-            let cloudPath = `https://laser-oss.4dkankan.com/${Potree.settings.webSite}/${Potree.settings.number}/data/bundle_${Potree.settings.number}/building/uuidcloud/${pano.uuid}/cloud.js`
+            let cloudPath = `${Potree.settings.urls.prefix1}/${Potree.settings.webSite}/${Potree.settings.number}/data/bundle_${Potree.settings.number}/building/uuidcloud/${pano.uuid}/cloud.js`
             
             let name = datasetId + '-'+pano.uuid
             let timeStamp = 0
@@ -901,6 +941,12 @@ changeLog() */
 
 
 
+---------
+
+lonlat和空间坐标其实并非线性关系,因为lonlat其实是角度。当两个数据集在地球两端时,它们之间的夹角都相差180度了。
+所以若要准确展示的话,需要将点云内所有物体,如漫游点,都先获取lonlat再去算local。或者直接将点云整体的transformMatrix考虑上在地球上相对于初始数据集的偏转。
+
+
    */
    
    

+ 1 - 1
src/custom/three.shim.js

@@ -229,7 +229,7 @@ THREE.Object3D.prototype.traverse = function ( callback ) {
     const children = this.children;
 
     for ( let i = 0, l = children.length; i < l; i ++ ) {  
-        children[ i ].traverse( callback ); 
+        children[ i ] && children[ i ].traverse( callback ); 
     } 
 }   
 

+ 0 - 20
src/custom/utils/Common.js

@@ -297,27 +297,7 @@ var Common = {
         }
     },
      
-    addOrRemoveDefine(material, defineName, type, value=''){ 
-        let defines = material.defines
-        if(type == 'add'){
-            if(defines[defineName] != void 0 && defines[defineName] == value)return
-            defines[defineName] = value
-        }else{
-            if(defines[defineName] != void 0)return;
-            delete defines[defineName] 
-        }
-        material.needsUpdate = true;
-    },
     
-    makeTexDontResize(map){//避免贴图因非2的次方而缩小。小心使用
-        if(!map || !map.image){  
-            return console.log('!map || !map.image', map, map&&map.image)
-        } 
-        if(THREE.Math.isPowerOfTwo(map.image.width ) && THREE.Math.isPowerOfTwo(map.image.height ))return
-        map.wrapS = map.wrapT = THREE.ClampToEdgeWrapping; //原默认 RepeatWrapping 
-        map.minFilter = THREE.LinearFilter; // or THREE.NearestFilter  原默认 LinearMipmapLinearFilter
-        map.needsUpdate = true
-    }
     
 }  
 

+ 14 - 2
src/custom/utils/DrawUtil.js

@@ -10,6 +10,18 @@ import {Features} from "../../Features.js";
 
 var defaultColor = new THREE.Color(1,1,1);//config.applicationName == "zhiHouse" ? Colors.zhiBlue : Colors.lightGreen;
 
+function dealPosArr(points){//识别是否每个点都不一样,把连续点变为不连续的片段连接 
+    if(points.length > 2 && !points[2].equals(points[1])){
+        let points2 = [] , len = points.length 
+        for(let i=0;i<len-1;i++){
+            points2.push(points[i], points[i+1])
+        } 
+        return points2
+    }else return points
+    
+} 
+
+
 var LineDraw = {
     
 	createLine: function (posArr, o={}) {
@@ -42,9 +54,9 @@ var LineDraw = {
 
 	},
     
-    
 	moveLine: function (line, posArr) {
         if(posArr.length == 0)return
+        posArr = dealPosArr(posArr)
         let position = []
         posArr.forEach(e=>position.push(e.x,e.y,e.z))
         line.geometry.setAttribute('position', new THREE.Float32BufferAttribute(/* new Float32Array( */position/* ) */, 3));
@@ -116,7 +128,7 @@ var LineDraw = {
 	moveFatLine: function(line, posArr){
 		var geometry = line.geometry;
         var positions = [];
-        
+        posArr = dealPosArr(posArr)
         posArr.forEach(e=>{positions.push(...e.toArray())})
          
 		 

+ 11 - 16
src/custom/utils/SplitScreen4Views.js

@@ -71,9 +71,9 @@ SplitScreen4Views.split = function(o={}){
     let mapViewport = viewer.mapViewer.viewports[0]   
     mapViewport.noPointcloud = false
     //隐藏地图游标
-    //viewer.updateVisible(viewer.mapViewer.cursor, 'split4Screens', false)
+    //Potree.Utils.updateVisible(viewer.mapViewer.cursor, 'split4Screens', false)
     /* viewer.images360.panos.forEach(pano=>{
-        viewer.updateVisible(pano.mapMarker, 'split4Screens', false) //希望这时候mapMarker已经建好了吧
+        Potree.Utils.updateVisible(pano.mapMarker, 'split4Screens', false) //希望这时候mapMarker已经建好了吧
     }) */
         
         
@@ -166,7 +166,7 @@ SplitScreen4Views.split = function(o={}){
 
 SplitScreen4Views.recover = function(){
     this.unSplit()
-    
+    viewer.mapViewer.viewports[0].beforeRender = null; 
     /* const {width, height} = viewer.renderer.getSize(new THREE.Vector2());
     viewer.renderer.setViewport(0,0,width,height)
     viewer.renderer.setScissorTest( false ); */
@@ -186,9 +186,9 @@ SplitScreen4Views.recover = function(){
     
     let mapViewport = viewer.mapViewer.viewports[0]
     viewer.mapViewer.attachToMainViewer(false) 
-    //viewer.updateVisible(viewer.mapViewer.cursor, 'split4Screens', true)
+    //Potree.Utils.updateVisible(viewer.mapViewer.cursor, 'split4Screens', true)
     /* viewer.images360.panos.forEach(pano=>{
-        viewer.updateVisible(pano.mapMarker, 'split4Screens', true)
+        Potree.Utils.updateVisible(pano.mapMarker, 'split4Screens', true)
     }) */
     mapViewport.noPointcloud = true
     { 
@@ -225,7 +225,7 @@ SplitScreen4Views.recover = function(){
 
 SplitScreen4Views.updateMapViewerBG = function(){
     let mapViewport = viewer.mapViewer.viewports[0]
-    if(this.floorplanEnabled || this.mapEnabled){
+    if( this.floorplanEnabled ||  this.mapEnabled){
         mapViewport.background = 'overlayColor'
         mapViewport.backgroundColor = new THREE.Color(0,0,0)
         mapViewport.backgroundOpacity = 0.5; 
@@ -234,23 +234,18 @@ SplitScreen4Views.updateMapViewerBG = function(){
         mapViewport.backgroundColor = null
         mapViewport.backgroundOpacity = null
     }
+    viewer.mapViewer.mapChanged = true
+    viewer.mapViewer.needUpdate = true
 }
 
-SplitScreen4Views.setFloorplanDisplay = function(e, show=false){ 
-    //viewer.updateVisible(e.floorplan.objectGroup, 'splitScreen', !!show)  
-    //e.floorplan.objectGroup.visible = !!show  
-    //viewer.mapViewer.mapLayer.needUpdate = true
+SplitScreen4Views.setFloorplanDisplay = function(e, show=false){  
     e.floorplan.setEnable(show)
 }
 
  
 SplitScreen4Views.enableMap = function(enable){ 
-    let map = viewer.mapViewer.mapLayer.maps.find(e=>e.name == 'map')
-    //viewer.updateVisible(map.objectGroup, 'splitScreen', !!enable) 
-    //map.objectGroup.visible = !!enable
-    //if(enable)viewer.mapViewer.mapLayer.needUpdate = true //加载地图
-    map.setEnable(!!enable)
-    
+    let map = viewer.mapViewer.mapLayer.maps.find(e=>e.name == 'map') 
+    map.setEnable(!!enable) 
     
     //viewer.mapViewer.mapGradientBG = viewer.background == 'gradient' && !enable
     this.mapEnabled = enable

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 224 - 576
src/custom/viewer/ViewerNew.js


+ 4 - 2
src/custom/viewer/Viewport.js

@@ -4,10 +4,10 @@
 import * as THREE from "../../../libs/three.js/build/three.module.js";
 import Common from '../utils/Common.js'
 
-export default class Viewport{
+export default class Viewport extends THREE.EventDispatcher{
     
     constructor( view, camera, prop={}){//目前不支持换camera
-        
+        super()
         this.left = prop.left;
         this.bottom = prop.bottom;
         this.width = prop.width;
@@ -87,5 +87,7 @@ export default class Viewport{
         this.resolution2.copy(this.resolution).multiplyScalar(this.pixelRatio || window.devicePixelRatio)
          
         this.offset.set(wholeW,wholeH).multiply(new THREE.Vector2(this.left,this.bottom))//.multiplyScalar(window.devicePixelRatio) 
+    
+        this.dispatchEvent({type:'resize'}) 
     }
 }

+ 241 - 157
src/custom/viewer/map/Map.js

@@ -1,6 +1,6 @@
 import * as THREE from "../../../../libs/three.js/build/three.module.js";
- 
-
+import math from '../../utils/math.js'
+import browser from '../../utils/browser.js'
 
 let texLoader = new THREE.TextureLoader() 
     texLoader.crossOrigin = "anonymous" 
@@ -30,16 +30,19 @@ let tempVector = new THREE.Vector3,  //sharedata
 
 
 
-const HALF_WORLD_SIZE = 21e6 
+const HALF_WORLD_SIZE = 21e6 //略大于半个周长(mapSizeM/2)
 const MAX_VERTICAL_DIST = 2 
 const MAX_VERTICAL_DIST_TO_BEST = 1  
  
-
+function defineLocalProj(locationLonLat){ 
+     proj4.defs("LOCAL_MAP", "+proj=tmerc +ellps=WGS84 +lon_0=" + locationLonLat[0].toPrecision(15) + " +lat_0=" + locationLonLat[1].toPrecision(15));
+}
+ 
 
 
 
 //高德坐标拾取工具 : https://lbs.amap.com/tools/picker
-
+ 
 
 export class MapLayer extends THREE.EventDispatcher{ // 包括了 MapLayerBase SceneLayer
     constructor(viewer_, viewport){
@@ -52,7 +55,7 @@ export class MapLayer extends THREE.EventDispatcher{ // 包括了 MapLayerBase S
         this.maps = [] 
         this.frustum = new THREE.Frustum 
         this.frustumMatrix = new THREE.Matrix4 
-        this.tileColor = /* i && i.tileColor ? i.tileColor :  */new THREE.Color(16777215)
+        this.tileColor =  new THREE.Color(16777215)
         this.viewport = viewport
         this.changeViewer(viewer_) 
         //添加地图
@@ -61,18 +64,13 @@ export class MapLayer extends THREE.EventDispatcher{ // 包括了 MapLayerBase S
         
 
         //map.setEnable(false)
-        
-        
-        
-        
-        /* this.on('needUpdate',()=>{ 
-            this.mapLayer.update()
-        }) 
-          */
+          
+       
     }
     
-    addMapEntity(data, datasetId){
-         
+    
+    
+    addMapEntity(data, datasetId){ 
         if(!data || !data[0]){ 
             Potree.Log('平面图无数据','red')
             return
@@ -116,6 +114,7 @@ export class MapLayer extends THREE.EventDispatcher{ // 包括了 MapLayerBase S
         this.maps.push(t)
         //this.view.invalidateScene()
         this.needUpdate = true
+        this.viewer.mapChanged = true
     }
      
     removeMap(t){
@@ -126,10 +125,9 @@ export class MapLayer extends THREE.EventDispatcher{ // 包括了 MapLayerBase S
         }
          
         /* this.view.invalidateScene() */ 
-        this.needUpdate = true
-        this.viewer.dispatchEvent({
-            type:'content_changed'
-        }) 
+        this.needUpdate = true 
+        this.viewer.mapChanged = true
+                
     }
     
      
@@ -152,34 +150,25 @@ export class MapLayer extends THREE.EventDispatcher{ // 包括了 MapLayerBase S
                 e[t].removeFromSceneGroup(this.sceneGroup)
             }
     }
-    
-    onAfterRenderViewport(e){
-        var n = this;
-        
-        /* this.isVisibleInViewport(e) && (this.updateTimer || this.loadingInProgress || (this.updateTimer = window.setTimeout((function(){
-            n.update(e).then((function  (t){
-                t && n.loadComplete.emit(!0)
-            }
-            )).catch(u.handleWarning)
-        }
-        ), 100))) */
-    }
-     
+  
      
      
     update(){
         this.needUpdate = false
         if(this.disabled || !this.maps.find(e=>!e.disabled) || !this.maps.find(e=>e.objectGroup.visible)   )return  //add
-        
+        this.viewer.mapChanged = true
           
         var e, n, i, r, o;
         
         this.updateTimer = void 0,
         e = this.viewport.camera,
-        n = e.projectionMatrix.clone(),
+        n = e.projectionMatrix.clone() 
+        
+        let expandRatio = 1.3 
+        n.elements[0] /= expandRatio 
+        n.elements[5] /= expandRatio   // 为了缓存吗,使边界处也提前加载,扩大显示区域
         
-        n.elements[0] /= 1.5,
-        n.elements[5] /= 1.5,
+         
         this.frustumMatrix.multiplyMatrices(n, e.matrixWorldInverse),
         this.frustum.setFromProjectionMatrix(this.frustumMatrix),
         this.frustum.planes[4].setComponents(0, 0, 0, 0),
@@ -197,13 +186,7 @@ export class MapLayer extends THREE.EventDispatcher{ // 包括了 MapLayerBase S
                  
     }
      
-    getAttributions(){
-        for (var t = {}, e = 0, n = this.maps; e < n.length; e++){
-            n[e].fillAttributions(t)
-        }
-        return t
-    }
-     
+    
     updateProjection(){
         for (var t = 0, e = this.maps; t < e.length; t++){
             var n = e[t];
@@ -211,6 +194,9 @@ export class MapLayer extends THREE.EventDispatcher{ // 包括了 MapLayerBase S
             n.updateObjectGroup()
         }
     }
+    
+    
+    
 }
  
     
@@ -236,7 +222,7 @@ export class TiledMapBase extends THREE.EventDispatcher{
         this.objectGroup = new THREE.Object3D;
         this.objectGroup.name = name
         this.objectGroupAdded = !1,
-        this.baseTile = new MapTile(this,/*   this.mapLayer, */this.objectGroup,this.tileColor),
+        this.baseTile = new MapTile(this, this.objectGroup, this.tileColor, null, '0'),
         this.isTileVisibleBox = new THREE.Box3,
         this.isTileVisibleVec = new THREE.Vector3
         
@@ -244,6 +230,12 @@ export class TiledMapBase extends THREE.EventDispatcher{
         this.projection = projection
         this._zoomLevel = 0;//1-20
         
+        
+        this.objectGroup.addEventListener('isVisible',()=>{
+            this.mapLayer.viewer.mapChanged = true
+        })
+        
+        this.computeCount = 0
     }
     
     get zoomLevel(){
@@ -266,29 +258,32 @@ export class TiledMapBase extends THREE.EventDispatcher{
     }
     
     updateProjection(){
-        //this.transformMapToLocal || (this.transformMapToLocal = this.TransformService.getTransform(this.projection, this.TransformService.crsLocal))
+         
         if(!this.transformMapToLocal){
-            if(proj4.defs("NAVVIS:TMERC")){
-                if(this.projection == "EPSG:4550"){
+            if(proj4.defs("LOCAL_MAP")){
+                /* if(this.projection == "EPSG:4550"){
                     this.transformMapToLocal = {
                             forward:(e)=>{
                                 var a = viewer.transform.lonlatTo4550.inverse(e)
                                 return viewer.transform.lonlatToLocal.forward(a)
                             },
-                        }
-                        
-                   
-                }else{
-                    this.transformMapToLocal = proj4(this.projection, "NAVVIS:TMERC") 
-                }
-                    //this.transformMapToLocal = proj4(this.projection, "NAVVIS:TMERC") 
-             
-               
+                        } 
+                }else{ */
+                     
+                    this.transformMapToLocal = proj4(this.projection, "LOCAL_MAP") 
+                    
+                    
+                    
+                //} 
             }
-        } 
-    
+        }  
     } 
     
+    clearProjection(){
+        this.transformMapToLocal = void 0 
+        this.projection !== 'LOCAL_MAP' && this.baseTile.remove()
+    }
+    
     setEnable(enable){//add
         if(!this.disabled == enable)return
         if(enable){
@@ -296,30 +291,24 @@ export class TiledMapBase extends THREE.EventDispatcher{
         }
         this.disabled = !enable
      
-        viewer.updateVisible(this.objectGroup, 'setEnable', enable)
+        Potree.Utils.updateVisible(this.objectGroup, 'setEnable', enable)
         
         if(!enable){
             this.baseTile.remove()
         }else{
             this.mapLayer.needUpdate = true
         }
-         
-        this.mapLayer.viewer.dispatchEvent({
-            type:'content_changed'
-        })
+       
+       
         
+               
         
     }
     
     
-    
-    /* clearProjection(){
-        this.transformMapToLocal = void 0,
-        this.projection.name !== this.TransformService.NAVVIS_LOCAL && this.baseTile.remove()
-    } */
-    
+   
     update(e, n){
-        
+        this.computeCount = 0 
         var unavailable = (this.disabled || !this.objectGroup.visible)//地图即使不显示也要获得zoomlevel
         if(this.name != 'map' && unavailable)return 
         
@@ -327,7 +316,7 @@ export class TiledMapBase extends THREE.EventDispatcher{
         
         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
@@ -346,12 +335,33 @@ export class TiledMapBase extends THREE.EventDispatcher{
         i.x *= a / 2,
         i.y *= s / 2;
         
-        var c = this.tileSizePx / i.length()
+        
+        //add 高纬度的因倾斜而造成tile较小,所以放大些,否则会造成显示的tile过多而卡
+        let lonlat = viewer.transform.lonlatToLocal.inverse(viewport.camera.position.clone()) 
+        let cos = Math.cos(THREE.Math.degToRad(lonlat.y)); //越小就在纬度上越高,tile表现越小
+        //为什么lonlat.y会超出90?
+        if(lonlat.y>90){
+            console.log('lonlat.y>90',lonlat.y)
+        } 
+        
+        cos = THREE.Math.clamp(cos, 0,1)
+        let lonShift =  Math.abs(viewer.mapViewer.camera.position.x / this.mapSizeM * 16  )  //越大就在经度离中心越远,tile表现越大  。  
+        lonShift = THREE.Math.clamp(lonShift, 0, Math.PI)
+        lonShift = (1 - Math.sin( 1/2 * lonShift +  Math.PI/2 )) * Math.PI // 0-Math.PI   sin增速向上
+        
+        let scale = 0.5 * cos * (1+lonShift)  +    0.5 * Math.pow(cos, lonShift)   
+        var c = this.tileSizePx / i.length() / scale      //多除以一个scale缩放因子,scale越大level越小
           , 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) 
+        level = Math.min(level, void 0 === this.maxDepth ? 1 / 0 : this.maxDepth)  
         this.zoomLevel = level//add
-        //console.log(level)
+        
+        
+        /* if(isNaN(this.zoomLevel )){ 
+            console.log(level, cos , scale , lonlat )
+        } */
+        
         if(!unavailable){
             this.addToSceneGroup(n) 
             return this.baseTile.update(this, e, level, this.mapSizeM, 0, 0, "")
@@ -361,10 +371,12 @@ export class TiledMapBase extends THREE.EventDispatcher{
      
      
      
-    isTileVisible(e, n, i){
-        if (n > HALF_WORLD_SIZE) return !0;
+    isTileVisible(e, n, i){ 
+        if (n > HALF_WORLD_SIZE) return !0; 
         var r = .5 * n;
-        this.transformMapToLocal.forward(e) 
+         
+        //简单版:
+        this.transformMapToLocal.forward(e) //e转化为local
         this.isTileVisibleBox.makeEmpty() 
         this.isTileVisibleVec.set(e.x - r, e.y - r, e.z).applyMatrix4(this.objectGroup.matrixWorld)
         this.isTileVisibleBox.expandByPoint(this.isTileVisibleVec)
@@ -373,8 +385,41 @@ export class TiledMapBase extends THREE.EventDispatcher{
         this.isTileVisibleVec.set(e.x + r, e.y - r, e.z).applyMatrix4(this.objectGroup.matrixWorld)
         this.isTileVisibleBox.expandByPoint(this.isTileVisibleVec)
         this.isTileVisibleVec.set(e.x + r, e.y + r, e.z).applyMatrix4(this.objectGroup.matrixWorld)
+        this.isTileVisibleBox.expandByPoint(this.isTileVisibleVec) 
+          
+      
+        
+        //仿造createMesh写的准确版,但会因为大的tile非矩形,而视口是矩形,若视口刚好在tile的曲线边缘外却识别为可见,就会创建冗余tile。 但上面那个简单版在zoomlevel低的时候地球边缘容易有识别不到的tile,造成黑色三角形。
+        //容易出现奇怪的mesh
+         /* this.isTileVisibleBox.makeEmpty()
+        this.isTileVisibleVec.set(e.x - r, e.y - r, e.z) 
+        this.transformMapToLocal.forward(this.isTileVisibleVec)
+        this.isTileVisibleVec.applyMatrix4(this.objectGroup.matrixWorld)
         this.isTileVisibleBox.expandByPoint(this.isTileVisibleVec)
-        return i.intersectsBox(this.isTileVisibleBox)
+        
+        this.isTileVisibleVec.set(e.x - r, e.y + r, e.z) 
+        this.transformMapToLocal.forward(this.isTileVisibleVec)
+        this.isTileVisibleVec.applyMatrix4(this.objectGroup.matrixWorld)
+        this.isTileVisibleBox.expandByPoint(this.isTileVisibleVec)
+        
+        this.isTileVisibleVec.set(e.x + r, e.y - r, e.z) 
+        this.transformMapToLocal.forward(this.isTileVisibleVec)
+        this.isTileVisibleVec.applyMatrix4(this.objectGroup.matrixWorld)
+        this.isTileVisibleBox.expandByPoint(this.isTileVisibleVec)
+        
+        this.isTileVisibleVec.set(e.x + r, e.y + r, e.z) 
+        this.transformMapToLocal.forward(this.isTileVisibleVec)
+        this.isTileVisibleVec.applyMatrix4(this.objectGroup.matrixWorld)
+        this.isTileVisibleBox.expandByPoint(this.isTileVisibleVec)  */
+            
+       
+        return i.intersectsBox(this.isTileVisibleBox)  
+         
+        
+        
+         
+        
+        
     }
      
     addToSceneGroup(t){
@@ -392,9 +437,10 @@ export class TiledMapBase extends THREE.EventDispatcher{
 }
 
 export class MapTile{
-    constructor(map,/*  t, */ e, n){
+    constructor(map,  e, n, parent, name){
         this.map = map;
-        //this.mapLayer = t,
+        this.name = name; 
+        this.parent = parent;
         this.objectGroup = e,
         this.tileColor = n,
         this.meshAdded = !1,
@@ -420,7 +466,7 @@ export class MapTile{
         if(this.textureLoaded){
             this.removeChildren() 
         }
-        
+         
         return this.textureLoaded
     }
     
@@ -438,9 +484,11 @@ export class MapTile{
                 var f = a + u[p]
                   , m = s + d[p];
                 tempVector.set(f, m, 0);
-                if (entity.isTileVisible(tempVector, .5 * o, n)){
-                     
-                    this.children[p] || (this.children[p] = new MapTile(this.map, this.objectGroup,this.tileColor))
+                this.map.computeCount ++
+                //console.log(this.map.computeCount, this.name, 'level:',level)
+                
+                if (entity.isTileVisible(tempVector, .5 * o, n)){ 
+                    this.children[p] || (this.children[p] = new MapTile(this.map, this.objectGroup,this.tileColor, this, this.name+p ))
                     l = this.children[p].update(entity, n, level - 1, .5 * o, f, m, h) && l
                 } else {
                     if (this.children[p]){
@@ -449,7 +497,7 @@ export class MapTile{
                     }
 
                 }
-                 
+                
             }
         }
         return l && this.removeObject3D(),
@@ -466,10 +514,16 @@ export class MapTile{
           , u = n / e + .5 * (c - 1)
           , d = -a / e + .5 * (c - 1)
           , p = t.getTileUrl(Math.round(l), Math.round(u), Math.round(d));
-        viewer.setObjectLayers(this.mesh, 'map' )
+        Potree.Utils.setObjectLayers(this.mesh, 'map' )
         this.mesh.renderOrder = -(1e6 - l - 100 * (t.zIndex || 0));
+        this.mesh.name = this.name //add
         var h = this.mesh.material;
         
+        /* let area = math.getArea(this.mesh.geometry.vertices.slice(0,3));
+        if(area >0){
+            this.mesh.visible = false
+            console.log('area>0',this.mesh.name)
+        } */
         
         var loadDone = ()=>{
             this.map.mapLayer.loadingInProgress--
@@ -483,10 +537,8 @@ export class MapTile{
                 this.textureLoaded = true
                 this.mesh.material.opacity = 1
                 //this.mapLayer.view.invalidateScene()
-                
-                this.map.mapLayer.viewer.dispatchEvent({
-                    type:'content_changed'
-                })
+                 
+                this.map.mapLayer.viewer.mapChanged = true
                 this.map.mapLayer.needUpdate = true //表示还要继续update(以removeChildren)
             }else{
                 tex.dispose()   
@@ -498,9 +550,10 @@ export class MapTile{
                 this.mesh.material.dispose() //o.disposeMeshMaterial(this.mesh) 
                 this.mesh.material =  errorMaterial
                 //this.map.mapLayer.view.invalidateScene())
-                this.map.mapLayer.viewer.dispatchEvent({
-                    type:'content_changed'
-                }) 
+               
+                this.map.mapLayer.viewer.mapChanged = true
+                
+                
             } 
             loadDone()
         })) 
@@ -535,10 +588,21 @@ export class MapTile{
             depthWrite: !1,
             depthTest: !0,
             opacity: 0,
-            side: THREE.DoubleSide
+            side: THREE.DoubleSide,
+           
         });
-        return t.color = this.tileColor ? this.tileColor : new THREE.Color(16777215),
-        t
+        if(Potree.settings.isTest) {
+            var colorHue = Math.random()
+            t.color = new THREE.Color().setHSL(colorHue, 0.6, 0.92) 
+        }else{
+            t.color = this.tileColor ? this.tileColor : new THREE.Color(16777215) 
+        }
+        
+        return t
+    }
+    
+    traverse(f){//add
+        return THREE.Mesh.prototype.traverse.call(this,f)
     }
     
     remove(){
@@ -575,21 +639,39 @@ export class MapTile{
 
 
 
-
 proj4.defs("EPSG:3857", "+title=WGS 84 / Pseudo-Mercator +proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +no_defs")
 //这里地图世界的中心是不是lon:0,lat:0     
 
 export class TiledMapOpenStreetMap extends TiledMapBase{
     constructor(mapLayer, tileColor){
-        super('map', mapLayer, tileColor, /* "EPSG:4550" */  "EPSG:3857"  ) //EPSG projection
+        
+        let baseUrl, attribution, projection, maxDepth;
+        
+        
+        
+        
+        
+        if(Potree.settings.mapCompany == 'google'){
+            projection = "EPSG:900913"//"EPSG:4326"//4550
+            baseUrl = "https://mt2.google.com/vt/lyrs=m@159000000&hl=zh-CN&gl=cn&x=${x}&y=${y}&z=${z}&s=mt1"  /* "http://mt2.google.cn/vt/lyrs=m@177000000&hl=zh-CN&gl=cn&src=app&x=${x}&y=${y}&z=${z}"  */   //最高只到19
+            attribution = "© PopSmart,  © 谷歌地图"
+            maxDepth = 22           
+        }else{
+            projection = "EPSG:3857"
+            baseUrl = "https://wprd04.is.autonavi.com/appmaptile?lang=zh_cn&style=7&x=${x}&y=${y}&z=${z}"    //最高只到19
+            attribution = "© PopSmart,  © 高德地图"
+            maxDepth = 19           
+        }
+        
+        super('map', mapLayer, tileColor,  projection ) //EPSG projection
         //this.baseUrl = "https://wprd03.is.autonavi.com/appmaptile?style=7&x=${x}&y=${y}&z=${z}",
         //this.baseUrl = "https://webrd01.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=7&x=${x}&y=${y}&z=${z}" //最高只到18 level
-        this.baseUrl = "https://wprd04.is.autonavi.com/appmaptile?lang=zh_cn&style=7&x=${x}&y=${y}&z=${z}"    //最高只到19
-        
-        this.attribution = "© PopSmart,  © 高德地图",
+        this.maxDepth = maxDepth
+        this.baseUrl = baseUrl; 
+        this.attribution = attribution
         this.tileSizePx = 256
-        this.mapSizeM = 40075017
-        this.maxDepth = 19//20
+        this.mapSizeM = 40075017   //总占据多少米(地球赤道周长)    和三维空间的不一样 - -, 空间上的是直径,地图上的是半个圆周
+        
         this.bias = 0.5 
          
   
@@ -598,24 +680,15 @@ export class TiledMapOpenStreetMap extends TiledMapBase{
     
     getTileUrl(t, e, n){ 
         return this.baseUrl.replace(/\${z}/, t.toString(10)).replace(/\${x}/, e.toString(10)).replace(/\${y}/, n.toString(10))
-    }
-     
-    fillAttributions(t){
-        t[this.attribution] = {
-            score: 50
-        }
-    }
-    
-    
-    
+    }  
 }
 
-
+//yrs=y为混合地图,s为卫星地图,m为普通地图。我们使用谷歌地图的瓦片图层的时候默认采用的是lyrs=s,也就是普通的卫星图层,现在我们希望包含路网信息,只需要设置lyrs=y就OK了。
 
 
 export class TiledMapFromEntity extends TiledMapBase{
     constructor(mapLayer, tileColor, data){ 
-        super('floorplan', mapLayer, tileColor,  "NAVVIS:TMERC"   /* "EPSG:3857"  *//* "WGS84" */)  //直接就是本地坐标,没有projec 
+        super('floorplan', mapLayer, tileColor,  "LOCAL"   /* "EPSG:3857"  *//* "WGS84" */)  //直接就是本地坐标,没有projec 
         
          
         let entity = this.tiledMapEntity = this.fillFromData(data)  
@@ -635,7 +708,7 @@ export class TiledMapFromEntity extends TiledMapBase{
         let data = {}
         
         data.id = e.id
-        data.globalLocation = Potree.Utils.VectorFactory.fromArray3(e.location),
+        data.globalLocation = Potree.Utils.VectorFactory.fromArray3(e.location)  
         data.orientation = Potree.Utils.QuaternionFactory.fromArray(e.orientation) 
         //if(Potree.fileServer){
             data.filePath = `${Potree.settings.urls.prefix1}${e.file_path}`
@@ -660,8 +733,15 @@ export class TiledMapFromEntity extends TiledMapBase{
     
     
     computeLocalCoordinates(){
-        if(proj4.defs("NAVVIS:TMERC")){
-            this.tiledMapEntity.location = new THREE.Vector3().copy(viewer.transform.lonlatToLocal.forward(this.tiledMapEntity.globalLocation))
+        if(proj4.defs("LOCAL_MAP")){
+            
+            let lonlat = this.tiledMapEntity.globalLocation
+            /* if(window.AMapWith84){//需要转换
+                lonlat = AMapWith84.wgs84ToAMap(lonlat) 
+            } */
+            lonlat = viewer.transform.lonlatToLocal.forward(lonlat)
+             
+            this.tiledMapEntity.location = new THREE.Vector3().copy(lonlat)
         } 
     }
      
@@ -691,13 +771,7 @@ export class TiledMapFromEntity extends TiledMapBase{
         return i += "?t=" + this.postStamp  
         //this.RestService.addAuthorizationQueryParameter(i) //????
     }
-    
-    fillAttributions(t) {
-        t.NavVis = {
-            score: 100
-        }
-    }
-   
+  
     
     
     
@@ -742,36 +816,46 @@ export class TiledMapFromEntity extends TiledMapBase{
 
 }
 
-
-/* { 
-    "bundle_id": 1,                         //t-CwfhfqJ
-    "file_name": "$DEPTH/$X/$Y.png",
-    "file_path": "data/bundle_t-CwfhfqJ/building_1/map_tiles/11",
-    "floor_id": 11,
-    "id": 1,
-    "location": [
-        113.5957510575092,
-        22.366605927999239,
-        0.0
-    ],
-    "map_size_m": 61.44,
-    "max_depth": 3,
-    "orientation": [
-        0.7071067811865476,
-        0.0,
-        0.0,
-        0.7071067811865475
-    ],
-    "quadtree": "fe5f7c7fcffff7f53",
-    "sceneCode": "t-CwfhfqJ",
-    "tile_size_px": 256,
-    "type": "TILED_PYRAMID"
-
-
-}
- */
-
-
-
+ /* 
+ note:
+ 
+ 
+ 
+ 目前缩小了能看出形态是一个地球。相机在高空朝下观测,地球平放着。
+ 所以越靠近赤道和地球朝上的那面所在的中央经度(也就是local 0,0,0所对应的初始经度),tile越接近正方形。
+ 
+ 所以在两极地区要怎么显示?
+ 注册地理坐标时需要滚动地球吗?(修改初始经度、重定义NAVVIS:TMERC, 就需要更新所有三维世界中的物体位置)
+ 
+ 
+ 切换中心点:
+    var locationLonLat = viewer.transform.lonlatToLocal.inverse(viewer.mapViewer.camera.position.clone())
+    proj4.defs("LOCAL_MAP", "+proj=tmerc +ellps=WGS84 +lon_0=" + locationLonLat.x.toPrecision(15) + " +lat_0=" + locationLonLat.y.toPrecision(15));  
+    viewer.mapViewer.mapLayer.maps[0].transformMapToLocal = null
  
 
+ 
+ 地理注册部分地图上的1和2标记有两层意思。当地图全屏展示时,标记的是当前右侧经纬度的位置;当地图为小窗时,标记的是对应场景里三维位置。(所以感觉最好换一个ui?)且在2023.2.1之前才改好,之前都是后者。
+ 
+ 
+ 
+ 为什么边缘总是有奇怪的mesh,是因为有顶点到背面了吗
+ 
+ 
+ 
+ https://lbs.amap.com/tools/picker  高德坐标拾取器,但和这里展示的不一样, 要转成84。
+ https://www.google.com/maps/@77.7730021,-34.4952712,4z     google取点
+ 
+ 
+ 
+ 
+ 打印所有mapTile的名字,字符串最长的代表有显示的mesh。
+ viewer.mapViewer.mapLayer.maps[0].baseTile.traverse(function(e){console.log(e.name)})
+ 
+ 
+ 能查看有几个显示的mesh
+ viewer.mapViewer.mapLayer.maps[0].objectGroup.children
+ 
+ 
+ 
+ */

+ 152 - 63
src/custom/viewer/map/MapViewer.js

@@ -45,7 +45,7 @@ export class MapViewer extends ViewerBase{
         })
         this.visible = true
         this.initScene()
-         
+        this.needRender_ = false 
          
         this.mapLayer = new MapLayer(this, this.viewports[0])
         this.scene.add(this.mapLayer.sceneGroup)
@@ -66,10 +66,20 @@ export class MapViewer extends ViewerBase{
         
         
         viewer.addEventListener("camera_changed", (e)=>{
-            if(e.viewport == viewer.mainViewport) this.updateCursor()
-            else this.updateWhenAtViewer() 
+            let needUpdateCursor
+            if(e.viewport == viewer.mainViewport){
+                needUpdateCursor = true
+            }else if(e.viewport == this.viewports[0]){//attachedToViewer
+                needUpdateCursor = true
+                this.mapChanged = true 
+                this.updateWhenAtViewer() 
+                e.changeInfo.projectionChanged && this.setViewLimit()
+            }
+            needUpdateCursor && this.updateCursor() 
         })
-        
+        this.addEventListener("camera_changed", (e)=>{
+            e.changeInfo.projectionChanged && this.setViewLimit()
+        }) 
          
         //viewer.addEventListener("global_mousemove", this.updateWhenAtViewer.bind(this))  //鼠标移动时reticule也动,所以直接就needRender
         viewer.reticule.addEventListener('update',(e)=>{
@@ -94,12 +104,16 @@ export class MapViewer extends ViewerBase{
             if(e.name == 'route'){
                 e.object.position.z = routeLayerHeight 
             } 
-            viewer.setObjectLayers(e.object, 'mapObjects' )
+            Potree.Utils.setObjectLayers(e.object, 'mapObjects' )
         })
         
         
-        
-        
+        viewer.addEventListener('allLoaded',()=>{
+            
+            this.setViewLimit('standard')
+            
+        })
+   
         
         if(!Potree.settings.isOfficial){
             let domRoot = viewer.renderer.domElement.parentElement; 
@@ -126,6 +140,20 @@ export class MapViewer extends ViewerBase{
     }
     
     
+    get needRender(){
+        return this.needRender_
+    }
+    set needRender(n){ 
+        this.needRender_ = n
+        n && (this.viewports[0].needRender = true) //使attachedToViewer时在renderDefault中可渲染
+    }
+    get mapChanged(){
+        return this.mapChanged_
+    }   
+    set mapChanged(c){//镜头移动、地图内容改变都会为true
+        this.mapChanged_ = c
+        c && (this.needRender = true)  
+    }
     
     
     
@@ -183,7 +211,7 @@ export class MapViewer extends ViewerBase{
         this.view = new ExtendView();
         this.view.position.set(0,0,Potree.config.map.cameraHeight);
         this.view.lookAt(0,0,0)
-        this.setViewLimit('standard')
+        
             
         let viewport = new Viewport( this.view, this.camera, {
             left:0, bottom:0, width:1, height: 1, name:'mapViewport'  
@@ -196,7 +224,9 @@ export class MapViewer extends ViewerBase{
         //viewport.unableDepth = true //depthBasicMaterial等在此viewport中不开启depth
         
         
-        
+        viewport.addEventListener('resize',()=>{
+            this.copyBuffer.setSize(viewport.resolution2.x, viewport.resolution2.y)
+        })
         this.viewports = [viewport]
         
                
@@ -227,18 +257,40 @@ export class MapViewer extends ViewerBase{
         this.cursor = cursor
        
         this.scene.add(cursor)
-        viewer.setObjectLayers(this.scene, 'mapObjects' )
+        Potree.Utils.setObjectLayers(this.scene, 'mapObjects' )
     }
     
     setViewLimit(state){//设置边界,当编辑空间模型等时要解禁
+        if(!state)state = this.limitBoundState
+        if(!state)return 
+        this.limitBoundState = state
+        
         let setting = Potree.config.OrthoCameraLimit[state]
-        if(setting){
-            this.view.limitBound = new THREE.Box3().copy(setting.posBound)
+        if(setting){ 
             this.camera.zoomLimit = $.extend({},setting.zoom);
+            
+             
+            let lonlatCenter = viewer.transform.lonlatToLocal.inverse([0,0]);
+            let minY = viewer.transform.lonlatToLocal.forward([lonlatCenter[0], -90+setting.latPad])[1] //屏幕边界的bound
+            let maxY = viewer.transform.lonlatToLocal.forward([lonlatCenter[0], 90-setting.latPad])[1] 
+            /*this.view.limitBound = new THREE.Box3(
+                new THREE.Vector3(setting.xBound[0], minY, Potree.config.map.cameraHeight), 
+                new THREE.Vector3(setting.xBound[1], maxY, 1 / 0)
+            )  */
+              
+            let halfHeight = this.viewports[0].resolution.y / 2 / this.camera.zoom;//屏幕所占高度的一半
+            let halfWidth = this.viewports[0].resolution.x / 2 / this.camera.zoom;
+            this.view.limitBound = new THREE.Box3(
+                new THREE.Vector3(setting.xBound[0]+halfWidth, minY+halfHeight, Potree.config.map.cameraHeight), 
+                new THREE.Vector3(setting.xBound[1]-halfWidth, maxY-halfHeight, 1 / 0)
+            ) 
+            
+            
         }else{  
             this.view.limitBound = null
             this.camera.zoomLimit  = null
         }
+        
     } 
     
     updateCursor(){
@@ -255,7 +307,7 @@ export class MapViewer extends ViewerBase{
     }
     
     addPanos(e){
-        var panosGroup = new THREE.Object3D;
+        var panosGroup = new THREE.Object3D;  panosGroup.name = 'markers'
         panoMarkerMats = {
             default: new THREE.MeshBasicMaterial({
                 transparent:true,
@@ -308,7 +360,7 @@ export class MapViewer extends ViewerBase{
             
             pano.addEventListener('isVisible',(e)=>{//是否显示该点的mesh(不显示也能走)   
                 //console.log('panoMarker isVisible', pano.id, e.visible)
-                viewer.updateVisible(pano.mapMarker, 'panoVisible', e.visible )
+                Potree.Utils.updateVisible(pano.mapMarker, 'panoVisible', e.visible )
                 this.needRender = true
                 
             })
@@ -319,7 +371,7 @@ export class MapViewer extends ViewerBase{
         this.scene.add(panosGroup)
         panosGroup.position.z = panosHeight
         this.panosGroup = panosGroup
-        viewer.setObjectLayers(panosGroup, 'mapObjects' )
+        Potree.Utils.setObjectLayers(panosGroup, 'mapObjects' )
         
         
         /* e.images.on('markersDisplayChange', (show)=>{
@@ -452,12 +504,10 @@ export class MapViewer extends ViewerBase{
     
     
     
-    updateWhenAtViewer(e){
+    updateWhenAtViewer(e){//两个触发来源: 1 camera_changed时  2 mapLayer.needUpdate时。  render在viewer中执行
         if(this.attachedToViewer){ 
-            if(this.started) this.mapLayer.update()  
-            
-            this.updateCursor() 
-            this.needRender = true
+            if(this.started) this.mapLayer.update()   
+            this.needRender = true 
         } 
     }
     
@@ -466,7 +516,7 @@ export class MapViewer extends ViewerBase{
         
         
         if(this.attachedToViewer){
-            if(this.mapLayer.needUpdate){//必须更新。(较少触发)
+            if(this.mapLayer.needUpdate){
                 this.updateWhenAtViewer()
             }
             return
@@ -481,18 +531,19 @@ export class MapViewer extends ViewerBase{
             
         let changed = this.cameraChanged() 
         
-        
+         
         if(this.started && (changed || this.mapLayer.needUpdate))this.mapLayer.update()
         
         if(changed /*||   || this.needRender */){ 
-            this.dispatchEvent({
+            /* this.dispatchEvent({
                 type: "camera_changed", 
                 camera: this.camera,
                 viewport : this.viewports[0]
-            })
-                 
+            }) */
+            this.mapChanged = true
             this.needRender = true
             this.updateCursor()//更改大小
+            
         }
         this.render()
         
@@ -596,80 +647,118 @@ export class MapViewer extends ViewerBase{
         }
     }
     
-    render(params={}){
+    render1(params={}){//viewer的preserveDrawingBuffer为false时的版本
         let needCopy, waitCopy
         if(!this.visible && !this.attachedToViewer || !this.needRender && !params.force){
             if(this.attachedToViewer ){
                 needCopy = true 
-            }else{
+            }else{ 
                 return
             } 
         }
         waitCopy = this.attachedToViewer && this.needRender && !params.force//是否写入到copyBuffer。双屏时,若needRender就拷贝到copyBuffer中,双屏时就直接使用copyBuffer。 四屏时因渲染点云会每帧都渲染,所以不需要缓存。
-        
-        
+         
         let renderer = params.renderer || this.renderer
         
-        if(params.target){
-            renderer.setRenderTarget(params.target)
-        }else if(waitCopy){
+        if(waitCopy){
             this.copyBuffer.setSize(params.viewport.resolution2.x, params.viewport.resolution2.y)
             renderer.setRenderTarget(this.copyBuffer) 
+        }else if(params.target){
+            renderer.setRenderTarget(params.target)
         }            
         /* if(params.resize){
             this.emitResizeMsg(new THREE.Vector2(params.width,params.height, viewport:params.viewport))
         }  */
         params.clear ? params.clear() : renderer.clear(); 
-        
-        if(!this.attachedToViewer){
+         
+        if(!needCopy || waitCopy){//重绘
             viewer.dispatchEvent({type: "render.begin",  viewer: this, viewport:this.viewports[0], params }); 
+            Potree.Utils.setCameraLayers(this.camera, ['map','mapObjects'  , 'bothMapAndScene'  ])
+            
+            if(this.mapGradientBG){//渲染背景
+                viewer.scene.cameraBG.layers.set(Potree.config.renderLayers.bg);
+                renderer.render(viewer.scene.scene, viewer.scene.cameraBG);
+            }
+            
+            renderer.render(this.scene, this.camera);
+            renderer.render(viewer.scene.scene, this.camera);
+            
+            //测量线等
+            //params.renderOverlay && params.renderOverlay( $.extend({}, params, { isMap:true }))
+             
+            renderer.setRenderTarget(params.target||null)
+        } 
+                     
+        if(needCopy || waitCopy){//使用缓存   ----当viewer的preserveDrawingBuffer为false的话,使用buffer
+            this.copyPass.render(null,null, renderer, params.target||null, this.copyBuffer)
+        }  
+        this.needRender = false
+        return true
+    }
+    
+    
+    
+    
+    //拆成两次渲染,一个地图一个其他物体,且地图渲染后保存在buffer中,只有当地图变化后才重渲染。 
+    render(params={}){ 
+    
+        if(!this.visible && !this.attachedToViewer || !this.needRender && !params.force){  //注意:mapViewer.needRender的权重高于它的viewport的needRender,也就是说,当attachedToViewer时,viewer即使needRender, mapViewer也不一定会渲染。
+            return 
+        } 
+        let renderer = params.renderer || this.renderer
+         
+        if(this.mapChanged){  //渲染地图背景
+            renderer.setRenderTarget(this.copyBuffer) 
+            params.clear ? params.clear() : renderer.clear(); 
+            
+            if(this.mapGradientBG){//渲染背景
+                viewer.scene.cameraBG.layers.set(Potree.config.renderLayers.bg);
+                renderer.render(viewer.scene.scene, viewer.scene.cameraBG);
+            } 
+            Potree.Utils.setCameraLayers(this.camera, ['map'])
+            renderer.render(this.scene, this.camera);
+            
+            params.renderBG && params.renderBG(this.viewports[0])
+            
+            this.mapChanged = false
+            renderer.setRenderTarget(params.target||null) 
         }
         
-        viewer.setCameraLayers(this.camera, ['map','mapObjects'  , 'bothMapAndScene'  ])
+        params.clear ? params.clear() : renderer.clear(); 
+        this.copyPass.render(null,null, renderer, params.target||null, this.copyBuffer) //拷贝地图背景
+        renderer.clearDepth(); //防止地图遮挡其他物体
         
-        if(this.mapGradientBG){//渲染背景
-            viewer.scene.cameraBG.layers.set(Potree.config.renderLayers.bg);
-            renderer.render(viewer.scene.scene, viewer.scene.cameraBG);
-        }
         
-        renderer.render(this.scene, this.camera);
-        renderer.render(viewer.scene.scene, this.camera);
-        
-        //测量线等
-        //params.renderOverlay && params.renderOverlay({camera:this.camera, isMap:true, viewport: this.viewports[0] })//其余如reticule 等场景层
-        //params.renderOverlay && params.renderOverlay( $.extend({}, params, { isMap:true }))
         
+        //绘制其他物体
+        Potree.Utils.setCameraLayers(this.camera, ['mapObjects'  , 'bothMapAndScene'  ])
+        viewer.dispatchEvent({type: "render.begin",  viewer: this, viewport:this.viewports[0], params }); 
+        renderer.render(this.scene, this.camera);
+        this.attachedToViewer || renderer.render(viewer.scene.scene, this.camera); //类同renderOverlay
         
+           
         renderer.setRenderTarget(null)
-        
+    
         this.needRender = false
         
-        if(needCopy || waitCopy){
-            this.copyPass.render(null,null, renderer, null, this.copyBuffer)
-        }
+        return true      
     }
-    
-    
-    /* render(){
-        
-        let camera =  viewer.scene.getActiveCamera();
-
-        viewer.scene.view.position.x += 0.01    
-
-        viewer.setCameraLayers(camera, ['sceneObjects','marker','reticule','skybox' ]) 
-        this.renderer.render(viewer.scene.scene, camera);  
-
 
-    } */
     
     
     
+     
+    
 }
 /* 
     渲染顺序:
-        地图、overlay
+        地图 
+        背景Overlay
+        地图scene的物体,如cursor、 marker
         点云(如果有)
-        场景中bothMapAndScene的物体
+        overlay,两层:第一层:viewer的scene中bothMapAndScene的如reticule. 第二层:如测量线(attachToMainViewer时才渲染)
+        
+         
 */
 //本地调试地图白屏是因为代码自动更新了 但没刷新
 

+ 9 - 7
src/custom/viewer/viewerBase.js

@@ -20,6 +20,7 @@ export class ViewerBase extends THREE.EventDispatcher{
          
         this.addEventListener('content_changed', ()=>{//画面改变,需要渲染
             this.needRender = true
+            //console.log('needRender')
         })
         
         
@@ -36,21 +37,21 @@ export class ViewerBase extends THREE.EventDispatcher{
         let height = this.renderArea.clientHeight;
 
         let contextAttributes = {
-            alpha: true,
+            alpha: true,//支持透明
             depth: true,
             stencil: false,
-            antialias: true, 
-            preserveDrawingBuffer: false    ,
+            antialias: !!args.antialias, 
+            preserveDrawingBuffer: args.preserveDrawingBuffer || false ,
             powerPreference: "high-performance",
         }; 
 
         let canvas = document.createElement("canvas");
                                                              
 
-        let context = canvas.getContext('webgl', contextAttributes );
+        let context = canvas.getContext('webgl', contextAttributes );   //不用webgl2是因为有的写法在webgl2不支持 如gl_FragDepthEXT 
+        
 
-        this.renderer = new THREE.WebGLRenderer({
-            alpha: true, //支持透明
+        this.renderer = new THREE.WebGLRenderer({ 
             premultipliedAlpha: false, 
             canvas: canvas,
             context: context, 
@@ -290,7 +291,8 @@ export class ViewerBase extends THREE.EventDispatcher{
                         changeInfo 
                     }) 
                     //this.changeTime = (this.changeTime || 0) +1
-                //} 
+                //}
+                 this.viewports[i].needRender = true  //直接写这咯   
             }                
         }
         return changed

+ 3 - 2
src/loader/BinaryLoader.js

@@ -38,7 +38,7 @@ export class BinaryLoader{
 			if (xhr.readyState === 4) {
 				if((xhr.status === 200 || xhr.status === 0) &&  xhr.response !== null){
 					let buffer = xhr.response;
-					this.parse(node, buffer);
+					this.parse(node, buffer); 
 				} else {
 					//console.error(`Failed to load file! HTTP status: ${xhr.status}, file: ${url}`);
 					throw new Error(`Failed to load file! HTTP status: ${xhr.status}, file: ${url}`);
@@ -53,7 +53,7 @@ export class BinaryLoader{
 		}
 	};
 
-	parse(node, buffer){//old
+	parse(node, buffer, callback){  
 		let pointAttributes = node.pcoGeometry.pointAttributes;
 		let numPoints = buffer.byteLength / node.pcoGeometry.pointAttributes.byteSize;
 
@@ -134,6 +134,7 @@ export class BinaryLoader{
 			node.loading = false;
 			node.estimatedSpacing = data.estimatedSpacing;
 			Potree.numNodesLoading--;
+            callback()//add
 		};
 
 		let message = {

+ 7 - 7
src/materials/shaders/depthBasic.fs

@@ -2,11 +2,6 @@ varying vec2 vUv;
 uniform float opacity;
 
 uniform vec3 baseColor;
-uniform vec3 backColor;
-uniform float occlusionDistance;
-uniform float clipDistance;
-uniform float maxClipFactor;
-
 
 #if defined use_map
     uniform sampler2D map; 
@@ -20,7 +15,12 @@ uniform float maxClipFactor;
     uniform float farPlane; 
     uniform vec2 resolution;
     uniform vec2 viewportOffset; //  viewportOffset 范围从0-整个画布的像素
-    
+    uniform vec3 backColor;
+    uniform float occlusionDistance;
+    uniform float clipDistance;
+    uniform float maxClipFactor;
+    uniform float maxOcclusionFactor;
+
     float convertToLinear(float zValue)
     {
         float z = zValue * 2.0 - 1.0;
@@ -65,7 +65,7 @@ void main() {
             // of the current fragment withing those zones.
             
             
-            mixFactor = clamp(delta / occlusionDistance, 0.0, 1.0);
+            mixFactor = clamp(delta / occlusionDistance, 0.0, maxOcclusionFactor);
             clipFactor = clamp(delta / clipDistance, 0.0, maxClipFactor);
         }
         

+ 22 - 1
src/materials/shaders/otherShaders.js

@@ -7,7 +7,11 @@ export const copyShader = {
         opacity: {
             type: "f",
             value: 1
-        }
+        },
+        depthTex: {
+            type: "t",
+            value: null
+        } 
     },
     vertexShader: ` 
         varying vec2 vUv;
@@ -17,12 +21,29 @@ export const copyShader = {
         }
     `,
     fragmentShader: `
+        #extension GL_EXT_frag_depth : enable
         uniform float opacity;
         uniform sampler2D tDiffuse;
+        #if defined(GL_EXT_frag_depth) && defined(useDepth)
+            uniform sampler2D depthTex;
+        #endif
+        
         varying vec2 vUv;
         void main() { 
+            #if defined(GL_EXT_frag_depth) && defined(useDepth)
+                float depth = texture2D(depthTex, vUv).r;
+                /* if(depth >= 1.0){ //超级远(但是在modelTex里我把天空距离超出far了,所以不删)
+                    discard;
+                } */
+                gl_FragDepthEXT = depth; 
+            #endif
+            
+            
+            
             vec4 texel = texture2D( tDiffuse, vUv );
             gl_FragColor = opacity * texel; 
+            
+            
         } 
      `    
 }

+ 17 - 5
src/navigation/InputHandlerNew.js

@@ -776,7 +776,8 @@ export class InputHandler extends THREE.EventDispatcher {
         let camera = viewport.camera
         let raycaster 
         
-        
+        let startTime = performance.now()
+
         let getByDepthTex = ()=>{
             /* if(prop.point){
                 raycaster = new THREE.Raycaster() 
@@ -899,6 +900,13 @@ export class InputHandler extends THREE.EventDispatcher {
         }
         
         
+        let endTime = performance.now()
+        //console.log('getIntersect费时:' ,parseInt((endTime-startTime)*100 )/100)
+        //点云费时:2-15ms
+        //深度图费时: 0.1-0.2ms
+
+        
+        
         if(onlyGetIntersect){ 
             return intersect
         }
@@ -955,7 +963,7 @@ export class InputHandler extends THREE.EventDispatcher {
         
             let dontIntersect =  this.drag && viewport.alignment || isFlying /* viewer.images360.flying */ // flying 时可能卡顿
             //console.log('dontIntersectPointcloud',dontIntersectPointcloud)
-            intersect = this.getIntersect(viewport,  e.onlyGetIntersect, e.pickWindowSize, !!dontIntersect, e.whichPointcloud) //数据集多的时候卡顿
+            intersect =  this.getIntersect(viewport,  e.onlyGetIntersect, e.pickWindowSize, !!dontIntersect, e.whichPointcloud) //数据集多的时候卡顿
             //console.log('intersectPoint', intersectPoint)
         } 
         
@@ -995,7 +1003,7 @@ export class InputHandler extends THREE.EventDispatcher {
                         type: 'drag',  //拖拽物体
                     }
                 ))
-                
+                viewer.dispatchEvent('content_changed') 
                 
             } else {
                  
@@ -1047,6 +1055,7 @@ export class InputHandler extends THREE.EventDispatcher {
                     }
                     
                     this.lastMouseoverElement = curr
+                    viewer.dispatchEvent('content_changed') 
                 }
 
                 if(hoveredElements.length > 0){
@@ -1059,7 +1068,7 @@ export class InputHandler extends THREE.EventDispatcher {
                             type: 'mousemove',
                             object: object
                         });
-                    }
+                    } 
                 }
                 this.hoveredElements = hoveredElements
             }
@@ -1194,6 +1203,7 @@ export class InputHandler extends THREE.EventDispatcher {
 			oldSelection: oldSelection,
 			selection: this.selection
 		});
+        viewer.dispatchEvent('content_changed') 
 	}
 
 	deselect(object){
@@ -1214,6 +1224,7 @@ export class InputHandler extends THREE.EventDispatcher {
 				selection: this.selection
 			});
 		}
+        viewer.dispatchEvent('content_changed') 
 	}
 
 	deselectAll () {
@@ -1233,6 +1244,7 @@ export class InputHandler extends THREE.EventDispatcher {
 				selection: this.selection
 			});
 		}
+        viewer.dispatchEvent('content_changed') 
 	}
 
 	isSelected (object) {
@@ -1315,7 +1327,7 @@ export class InputHandler extends THREE.EventDispatcher {
         raycaster.params.Line2 = {threshold :20 } //拓宽的lineWidth
         
         //raycaster.layers.enableAll()//add
-        viewer.setCameraLayers(raycaster,   //设置能识别到的layers(如空间模型里只有mapViewer能识别到marker)
+        Potree.Utils.setCameraLayers(raycaster,   //设置能识别到的layers(如空间模型里只有mapViewer能识别到marker)
             ['sceneObjects','mapObjects','measure',  'transformationTool', 'model'],
             this.hoverViewport && this.hoverViewport.extraEnableLayers
         )

+ 11 - 10
src/utils/TransformationToolNew.js

@@ -139,7 +139,7 @@ export class TransformationTool extends THREE.EventDispatcher{
         //------------------add-----------------------
         
         this.setModeEnable(['scale','translation','rotation'])
-        viewer.setObjectLayers(this.scene, 'transformationTool' )
+        Potree.Utils.setObjectLayers(this.scene, 'transformationTool' )
 		
         this.scene.traverse(e=>{
             e.pickDontCheckDis = true; //pick时不需要识别是否在点云之上
@@ -170,6 +170,7 @@ export class TransformationTool extends THREE.EventDispatcher{
             this.addEventListener('transformed', (e)=>{ 
                 let object = viewer.transformationTool.selection[0]
                 this.history.beforeChange({object, matrix:e.matrixBefore.clone()} )
+                this.viewer.dispatchEvent('content_changed') 
             })
             this.addEventListener('stopDrag', (e)=>{ 
                 let object = viewer.transformationTool.selection[0]
@@ -194,7 +195,7 @@ export class TransformationTool extends THREE.EventDispatcher{
             let enable = enableModes.includes(mode)
             
             for(let o in handels){
-                viewer.updateVisible(handels[o].node,'modeForce', !!enable) 
+                Potree.Utils.updateVisible(handels[o].node,'modeForce', !!enable) 
             }
             this.modesEnabled[mode] = !!enable
             
@@ -217,7 +218,7 @@ export class TransformationTool extends THREE.EventDispatcher{
         ['x','y','z'].forEach(axis=>{
             this.translationHandles['translation.'+axis].node.children.forEach(mesh=>{
                 if(mesh.name.includes('arrow')){
-                    viewer.updateVisible(mesh, 'modeStyle', style == 'singleMode') 
+                    Potree.Utils.updateVisible(mesh, 'modeStyle', style == 'singleMode') 
                 }else if(mesh.name.includes('handle')){
                     mesh.material.lineWidth = style == 'singleMode' ? 5 : 8
                 }
@@ -233,7 +234,7 @@ export class TransformationTool extends THREE.EventDispatcher{
             handle.node.children[0].position.fromArray(handle.alignment2).multiplyScalar(s*1.5)        
         })
         
-        viewer.updateVisible(this.scaleHandles['lines'].node, 'modeStyle', style == 'singleMode') 
+        Potree.Utils.updateVisible(this.scaleHandles['lines'].node, 'modeStyle', style == 'singleMode') 
         
         
         this.style = style
@@ -1019,10 +1020,10 @@ export class TransformationTool extends THREE.EventDispatcher{
 
 
 		if(handle){
-			handle.node.setOpacity(1.0);
+			handle.node.setOpacity(1.0); 
 		}
-
-		
+        
+		viewer.dispatchEvent('content_changed') 
 	}
 
 	update () {
@@ -1141,7 +1142,7 @@ export class TransformationTool extends THREE.EventDispatcher{
                     
                     
                     //xzw add:---- -当该轴正对相机时隐藏。(主要针对ortho类型camera。 
-                    if(!viewer.getObjVisiByReason(node,'modeForce')  )continue;   
+                    if(!Potree.Utils.getObjVisiByReason(node,'modeForce')  )continue;   
                     
                     let alignment = handle.alignment;
                     if(alignment && (!handleName.includes('rotation') || camera.type == 'OrthographicCamera')){//旋转的话正常都应该显示
@@ -1161,9 +1162,9 @@ export class TransformationTool extends THREE.EventDispatcher{
                             ifOnLine = Math.abs(dir.dot(normal)) > 0.995
                         }
                         
-                        viewer.updateVisible(node, 'faceToCamHide', !ifOnLine)
+                        Potree.Utils.updateVisible(node, 'faceToCamHide', !ifOnLine)
                     }else{
-                        viewer.updateVisible(node, 'faceToCamHide', true)
+                        Potree.Utils.updateVisible(node, 'faceToCamHide', true)
                     }      
                      
                     if(!node.visible)continue;   

+ 1 - 1
src/utils/VolumeNew.js

@@ -210,7 +210,7 @@ export class BoxVolume extends Volume{
 		this.boundingSphere = this.boundingBox.getBoundingSphere(new THREE.Sphere());
 
 		 
-        viewer.updateVisible(this.box, 'selected', (this.selected || this.hovered) && this.showBox) 
+        Potree.Utils.updateVisible(this.box, 'selected', (this.selected || this.hovered) && this.showBox) 
         
         this.box.material.opacity = this.selected ? boxOpacity.selected : boxOpacity.hovered
         

+ 72 - 60
src/viewer/EDLRendererNew.js

@@ -7,9 +7,8 @@ import {Utils} from "../utils.js";
 import {copyShader} from '../materials/shaders/otherShaders.js'
 import {Features} from "../Features.js";
 import {easing} from "../custom/utils/transitions.js";
-
-
-
+ 
+//import DepthTexSampler from "../custom/utils/DepthTexSampler.js";
 
 export class EDLRenderer{//Eye-Dome Lighting 眼罩照明
 	constructor(viewer){
@@ -26,10 +25,11 @@ export class EDLRenderer{//Eye-Dome Lighting 眼罩照明
         
         viewer.addEventListener('resize',this.resize.bind(this))
         this.initEDL(viewer) 
+        
 	}
 
 	initEDL(viewer){
-		if (this.edlMaterial != null) {
+		if (this.edlMaterial != null || !Features.EXT_DEPTH.isSupported()){
 			return;
 		}
 
@@ -38,39 +38,42 @@ export class EDLRenderer{//Eye-Dome Lighting 眼罩照明
 		this.edlMaterial.depthWrite = true;
 		this.edlMaterial.transparent = true;
         
-         
-
-		/* this.rtRegular = new THREE.WebGLRenderTarget(viewer.mainViewport.resolution2.x, viewer.mainViewport.resolution2.y, {
-			minFilter: THREE.NearestFilter,
-			magFilter: THREE.NearestFilter,
-			format: THREE.RGBAFormat,
-			depthTexture: new THREE.DepthTexture(undefined, undefined, THREE.UnsignedIntType)
-		});
-         */
-        
-        
-        
-        
-       /*  let copyUniforms = THREE.UniformsUtils.clone( copyShader.uniforms );
+        let copyUniforms = THREE.UniformsUtils.clone( copyShader.uniforms );
+        this.recoverToScreenMat = new THREE.ShaderMaterial({
           
-        this.copyMaterial = new THREE.ShaderMaterial(	{
             uniforms: copyUniforms,
-            vertexShader: copyShader.vertexShader,
-            fragmentShader: copyShader.fragmentShader,
-            //premultipliedAlpha: true,
-            transparent: true,
-            //blending: THREE.AdditiveBlending,
-            depthTest: false,
-            depthWrite: false
-        }); */
-        
+            vertexShader:copyShader.vertexShader,
+            fragmentShader: copyShader.fragmentShader, 
+            transparent: true,         
+            defines:{
+                useDepth: true
+            }            
+        })
+        /*  let copyUniforms = THREE.UniformsUtils.clone( copyShader.uniforms );
+          
+            this.copyMaterial = new THREE.ShaderMaterial(	{
+                uniforms: copyUniforms,
+                vertexShader: copyShader.vertexShader,
+                fragmentShader: copyShader.fragmentShader,
+                //premultipliedAlpha: true,
+                transparent: true,
+                //blending: THREE.AdditiveBlending,
+                depthTest: false,
+                depthWrite: false
+            }); */
+        if(Potree.settings.testRT){
+            viewer.images360.addEventListener('endChangeMode',()=>{
+                this.resize({viewport:viewer.mainViewport})
+            }) 
+        }
+        //this.depthTexSampler = new DepthTexSampler(this);
 	};
 
-	resize(e ){
+	resize(e){
         if(Features.EXT_DEPTH.isSupported()){  
             let viewport = e.viewport
-             
-            this.getRtEDL(viewport).setSize(  viewport.resolution.x, viewport.resolution.y  );   //理论上可以是任意尺寸,但会影响精度,且aspect最好和渲染的一致
+            let size = Potree.settings.testRT && Potree.settings.displayMode == 'showPanos' ? viewport.resolution2 : viewport.resolution; //若要渲染skybox,需要和设备一样精度的rt
+            this.getRtEDL(viewport).setSize( size.x, size.y  );   //理论上可以是任意尺寸,但会影响精度,且aspect最好和渲染的一致
         }
 	}
 
@@ -125,7 +128,7 @@ export class EDLRenderer{//Eye-Dome Lighting 眼罩照明
                     magFilter: THREE.NearestFilter,
                     format: THREE.RGBAFormat,
                     type: THREE.FloatType,
-                    depthTexture: new THREE.DepthTexture(undefined, undefined, THREE.UnsignedIntType)
+                    depthTexture: new THREE.DepthTexture(undefined, undefined, THREE.UnsignedIntType) 
                 }); 
                 //注: 部分手机在resize时会崩溃,经检验去掉rtEDL的resize可以解决,所以更应该注释掉这个
             
@@ -188,38 +191,47 @@ export class EDLRenderer{//Eye-Dome Lighting 眼罩照明
         const viewer = this.viewer; 
 		let camera = params.camera ? params.camera : viewer.scene.getActiveCamera();
 		const resolution = params.viewport ? params.viewport.resolution : this.viewer.renderer.getSize(new THREE.Vector2());//突然发现mobile用resolution2点云会放大
-		
+        let rtEDL = params.rtEDL || this.getRtEDL(params.viewport)
+        let target = params.target || null
+        viewer.renderer.setRenderTarget(target);
         
         //viewer.dispatchEvent({type: "render.pass.begin",viewer: viewer});
-	
-		       
+	 
 		let lights = [];
 		/* viewer.scene.scene.traverse(node => {
 			if(node.type === "SpotLight"){
 				lights.push(node);
 			}
 		}); */
-
-
-        viewer.renderer.setRenderTarget(params.target || null);
         
         
         //skybox  全景图
         if(!params.magnifier){
-            viewer.setCameraLayers(camera, ['skybox'])
+            Potree.Utils.setCameraLayers(camera, ['skybox'])
             let useDepthTex
             if(Potree.settings.displayMode == 'showPanos' && viewer.images360.currentPano.pointcloud.hasDepthTex && Features.EXT_DEPTH.isSupported()){//渲染深度图
                 useDepthTex = true
-                viewer.renderer.setRenderTarget(params.rtEDL || this.getRtEDL(params.viewport)) //将带有深度图的skybox画在rtEDL一下,这样就不需要绘制后边的点云了
+             
+                viewer.renderer.setRenderTarget(rtEDL) //将带有深度图的skybox画在rtEDL一下,这样就不需要绘制后边的点云了
                 viewer.renderer.render(viewer.scene.scene, camera);
-                viewer.renderer.setRenderTarget(params.target || null);
-            } 
-            viewer.renderer.render(viewer.scene.scene, camera);
+                viewer.renderer.setRenderTarget(target);
+                
+                if(Potree.settings.testRT){//直接使用rtEDL,但是会失去抗锯齿,不知在skybox上需要抗锯齿吗
+                    this.recoverToScreenMat.uniforms.depthTex.value = rtEDL.depthTexture
+                    this.recoverToScreenMat.uniforms.tDiffuse.value = rtEDL.texture  
+                    Utils.screenPass.render(viewer.renderer, this.recoverToScreenMat, target);  
+                }else{
+                    viewer.renderer.render(viewer.scene.scene, camera);
+                }
+            }else{
+                viewer.renderer.render(viewer.scene.scene, camera);
+            }                
+            
             if(useDepthTex)return 
         }  
          
         
-		const visiblePointClouds2 = viewer.scene.pointclouds.filter(pc => viewer.getObjVisiByReason(pc,'datasetSelection')  ); //需要绘制到rtEDL的
+		const visiblePointClouds2 = viewer.scene.pointclouds.filter(pc => Potree.Utils.getObjVisiByReason(pc,'datasetSelection')  ); //需要绘制到rtEDL的
 		const showPointClouds = params.magnifier ? visiblePointClouds2.length>0 : viewer.scene.pointclouds.some(e=>e.visible) //是否有需要绘制到屏幕的
          
         visiblePointClouds2.forEach(e=>{//为了绘制到depthTexture,先显示(展示全景图时隐藏了点云,所以需要显示下。且放大镜需要绘制点云)
@@ -229,7 +241,7 @@ export class EDLRenderer{//Eye-Dome Lighting 眼罩照明
 
         
          
-        viewer.setCameraLayers(camera, ['pointcloud'])
+        Potree.Utils.setCameraLayers(camera, ['pointcloud'])
         camera.layers.set(Potree.config.renderLayers.pointcloud);
 		
         //TODO adapt to multiple lights
@@ -240,9 +252,7 @@ export class EDLRenderer{//Eye-Dome Lighting 眼罩照明
                 
                 let material = pointcloud.material; 
                 let octreeSize = pointcloud.pcoGeometry.boundingBox.getSize(new THREE.Vector3()).x;
-                material.fov = THREE.Math.degToRad(camera.fov) 
-                /* material.screenWidth = width;
-                material.screenHeight = height; */
+                material.fov = THREE.Math.degToRad(camera.fov)  
                 material.resolution = resolution 
                
                 
@@ -264,15 +274,15 @@ export class EDLRenderer{//Eye-Dome Lighting 眼罩照明
                 
 			}
             
-            
+             
             if(Features.EXT_DEPTH.isSupported() && !params.dontRenderRtEDL){  
                 //借用rtEDL存储深度信息  
-                viewer.renderer.setRenderTarget(params.rtEDL || this.getRtEDL(params.viewport)/* this.rtEDL */);
+                viewer.renderer.setRenderTarget( rtEDL );
                
                
                 if(visiblePointClouds2.length>0){ 
                     //渲染scenePointCloud到rtEDL
-                    viewer.pRenderer.render(viewer.scene.scenePointCloud, camera, params.rtEDL || this.getRtEDL(params.viewport), {
+                    viewer.pRenderer.render(viewer.scene.scenePointCloud, camera,  rtEDL, {
                         shadowMaps:  lights.length > 0 ? [this.shadowMap] : null,
                         clipSpheres: viewer.scene.volumes.filter(v => (v instanceof SphereVolume)),
                         transparent: false,
@@ -292,7 +302,7 @@ export class EDLRenderer{//Eye-Dome Lighting 眼罩照明
                             obj.material = obj.depthMat
                         }
                     })
-                    viewer.setCameraLayers(camera, ['sceneObjects'])
+                    Potree.Utils.setCameraLayers(camera, ['sceneObjects'])
                     viewer.renderer.render(viewer.scene.scene, camera)
                     viewer.objs.traverse((obj)=>{
                         if(obj.material){
@@ -307,8 +317,8 @@ export class EDLRenderer{//Eye-Dome Lighting 眼罩照明
         
          
         //渲染到rtEDL完毕
-		viewer.dispatchEvent({type: "render.pass.scene", viewer: viewer/* , renderTarget: this.rtRegular */});
-		viewer.renderer.setRenderTarget(params.target || null);
+		viewer.dispatchEvent({type: "render.pass.scene", viewer: viewer });
+		viewer.renderer.setRenderTarget( target );
         
         if(!params.magnifier)visiblePointClouds2.forEach(e=>{//放大镜显示点云
             e.visible = e.oldVisi
@@ -338,16 +348,16 @@ export class EDLRenderer{//Eye-Dome Lighting 眼罩照明
                 projArray.set(proj.elements);
                 uniforms.uProj.value = projArray;
              
-                uniforms.uEDLColor.value = (params.rtEDL || this.getRtEDL(params.viewport)).texture;
-                //uniforms.uEDLDepth.value = (params.rtEDL || this.getRtEDL(params.viewport)).depthTexture; //其实没用到
+                uniforms.uEDLColor.value = rtEDL.texture;
+                //uniforms.uEDLDepth.value = rtEDL.depthTexture; //其实没用到
                  
                 uniforms.opacity.value = viewer.edlOpacity; // HACK
                  
                 
-                Utils.screenPass.render(viewer.renderer, this.edlMaterial, params.target);
-            }else{
-                //渲染点云 (直接用rtEDL上的会失去抗锯齿)
-                
+                Utils.screenPass.render(viewer.renderer, this.edlMaterial, target);  //相当于一个描边后期特效。 缺点: 因为target上的没有抗锯齿,所以点云在晃动镜头时会不稳定地闪烁1px位置。优点:比不打开edl少绘制一次点云,更流畅了?!
+            }else{ 
+                //渲染点云 (直接用rtEDL上的会失去抗锯齿, 导致频闪、密集时出现条纹,  自己写抗锯齿也要渲染好几次。另外透明度也要处理下 
+                   
                 let prop = {
                     shadowMaps:  lights.length > 0 ? [this.shadowMap] : null,
                     clipSpheres: viewer.scene.volumes.filter(v => (v instanceof SphereVolume)) ,
@@ -355,6 +365,8 @@ export class EDLRenderer{//Eye-Dome Lighting 眼罩照明
                 }
                  
                 viewer.pRenderer.render(viewer.scene.scenePointCloud, camera, null , prop);  
+                    
+                
             }
         }        
           

+ 4 - 4
src/viewer/ExtendScene.js

@@ -21,8 +21,8 @@ class ExtendScene extends Scene{
         //-------------
         this.axisArrow = new Axis();
         this.scene.add(this.axisArrow)
-        if(!Potree.settings.isDebug)this.axisArrow.visible = false
-        viewer.setObjectLayers(this.axisArrow,  'bothMapAndScene' )
+        if(!Potree.settings.isDebug && !Potree.settings.showAxis)this.axisArrow.visible = false
+        Potree.Utils.setObjectLayers(this.axisArrow,  'bothMapAndScene' )
         
         
         this.tags = new THREE.Object3D;
@@ -154,12 +154,12 @@ class ExtendScene extends Scene{
         
         //add:------给空间模型的box 或其他obj------
         let light2 = new THREE.AmbientLight( 16777215, 1 );
-        viewer.setObjectLayers(light2, 'bothMapAndScene')
+        Potree.Utils.setObjectLayers(light2, 'bothMapAndScene')
         this.scene.add(light2)
         let light3 = new THREE.DirectionalLight( 16777215, 1);  
         light3.position.set( 10, 10, 10 );
 		light3.lookAt( new THREE.Vector3(0, 0, 0));
-        viewer.setObjectLayers(light3, 'bothMapAndScene')
+        Potree.Utils.setObjectLayers(light3, 'bothMapAndScene')
         this.scene.add(light3)  
         //--------------------------------------------
 

+ 2 - 2
src/viewer/ExtendView.js

@@ -220,8 +220,8 @@ class ExtendView extends View {
                     this.rotation = new THREE.Euler().setFromQuaternion(quaternion)
                 }
                 this.restrictPos()
-                 
-
+                //console.log('setView flying')             
+ 
                 info.onUpdate && info.onUpdate(t)//add
             }), info.duration, done, 0, info.Easing ? easing[info.Easing] : easing.easeInOutSine /*easeInOutQuad */,null, this.LookTransition, info.cancelFun); 
 

+ 2 - 2
src/viewer/PropertyPanels/PropertiesPanel.js

@@ -6,7 +6,7 @@ import {Annotation} from "../../Annotation.js";
 import {Measure} from "../../utils/Measure.js";
 import {Profile} from "../../utils/Profile.js";
 import {Volume, BoxVolume, SphereVolume} from "../../utils/Volume.js";
-import {CameraAnimation} from "../../modules/CameraAnimation/CameraAnimation.js";
+import {CameraAnimation} from "../../custom/modules/CameraAnimation/CameraAnimation.js"//"../../modules/CameraAnimation/CameraAnimation.js";
 import {PointSizeType, PointShape, ElevationGradientRepeat} from "../../defines.js";
 import {Gradients} from "../../materials/Gradients.js";
 
@@ -58,7 +58,7 @@ export class PropertiesPanel{
 			this.setCamera(object);
 		}else if(object instanceof Annotation){
 			this.setAnnotation(object);
-		}else if(object instanceof CameraAnimation){
+		}else if(object instanceof CameraAnimation){//改
 			this.setCameraAnimation(object);
 		}
 		

+ 4 - 0
src/viewer/Scene.js

@@ -137,6 +137,7 @@ export class Scene extends EventDispatcher{//base
 			'scene': this,
 			'volume': volume
 		});
+        viewer.dispatchEvent('content_changed')
 	}
 
 	addOrientedImages(images){
@@ -222,6 +223,7 @@ export class Scene extends EventDispatcher{//base
 				'volume': volume
 			});
 		}
+        viewer.dispatchEvent('content_changed')
 	};
 
 	addCameraAnimation(animation) {
@@ -276,6 +278,7 @@ export class Scene extends EventDispatcher{//base
 			'scene': this,
 			'measurement': measurement
 		});
+        viewer.dispatchEvent('content_changed')
 	};
 
 	removeMeasurement (measurement) {
@@ -287,6 +290,7 @@ export class Scene extends EventDispatcher{//base
 				'scene': this,
 				'measurement': measurement
 			});
+            viewer.dispatchEvent('content_changed')
 		}
 	}
 

+ 1 - 1
src/viewer/potree.css

@@ -868,7 +868,7 @@ body{
     box-sizing: border-box;
     width:300px; height:200px;
     right:0px;
-    top:0px;
+    bottom:0px;
     background:#fff;
 }
 

+ 53 - 6
改bug的历史.txt

@@ -1,3 +1,52 @@
+2023.1.4 
+
+cpu过高:(静止时)
+
+全景模式: 30-40  希望降到20以下   只绘制一次skybox:20-30   不渲染overlay: 15-35
+点云模式: 60  
+原本potree在无点云时也有30的cpu (15-36波动)
+
+若不渲染,cpu范围:5-20, 有时会到60咋回事。
+不 loop, cpu: 0
+仅update: cpu: 10
+仅render: cpu: 25 (全景)
+matterport无抗锯齿, 但potree关闭抗锯齿并无变化
+
+结论: 
+ cpu高的原因:1渲染到rtEDL,很多depthMaterial的都需要。 2 renderOverlay的,如marker。 
+		3 点云加载、遍历一定会耗cpu   (点云的优势究竟是什么,比4dkk好在哪?)
+
+
+navvis居然全景和点云都能做到0,因为静止、画面无改变时 不渲染  invalidateScene
+但是这样的好处似乎很小:1 降低电池损耗 2或许能在不渲染时加快资源加载。而画面一旦动起来,cpu还是很高。
+ 
+结局: 参照它们也做了静止时不渲染 viewer.dispatchEvent('content_changed') 
+
+
+
+
+ 
+ 
+ 
+
+ 
+
+
+2022.12.30
+全景漫游卡顿(持续了几个月的问题)
+特征:所有漫游点均是首次飞向它时流畅,但回头再走就容易卡。
+调试:不checkAndWaitForPanoLoad 然后updateCube  不卡。 和skybox的geo变化无关,不改geo也卡。
+进一步发现: 卡的时候uploadTile LoadComplete 经常到了2048。令只加载到1024不卡。所以似乎是加载越多tiles越卡。
+解决方案:maxNonBaseUploadsPerFrame由2降为1。也就是在飞行时每帧uploadTiles的个数降低。另外飞行时refreshUploadInterval的间隔增加。
+效果:确实降低了卡顿感。
+还有疑问:为何4dkk不卡呢?只是在cubeRenderTarget上draw而已呀。 大场景因模型复杂所以本身就卡。
+
+
+目前浏览器卡顿情况:
+良好:chrome、 edge
+微卡: qq 全景模式
+卡:opera
+很卡: firefox(点云模式也)
 
 2022.12.13
 
@@ -5,11 +54,9 @@
 原来是populateScoredPanos时的distanceSquared函数有问题
 
 2022.11.24
-
-
-
-全景模式为什么有时候变卡: 导航会一直加载点云,因一直getPointByScreen
-改完之后过渡很流畅。在此之前还将漫游模式的visibleNodes清空了,仅在不支持depthTex时length才不为0
+全景模式为什么有时候变卡:
+1 导航会一直加载点云,因一直getPointByScreen  (2d发来的请求) 
+2 将漫游模式的visibleNodes清空了,仅在不支持depthTex时length才不为0
 
 
 2022.8.30
@@ -305,7 +352,7 @@ tiledownloader下载完成会触发tiledownloader开始uploadTile.
 
 
 
-
+奇怪后面怎么没记录了?是不是被覆盖了?解决方案好像是在potreeRenderer里加了 gl.disable(gl.BLEND) 等 恢复为不透明