Browse Source

fix: 改乱了

xzw 2 years ago
parent
commit
f29a5f3873
86 changed files with 1575 additions and 37421 deletions
  1. 2 21
      src/Features.js
  2. 50 1063
      src/PointCloudOctree.js
  3. 10 11
      src/Potree.js
  4. 27 0
      src/custom/note.txt
  5. 776 2
      src/custom/potree.shim.js
  6. 0 5181
      src/custom/viewer.js
  7. 5 121
      src/defines.js
  8. 1 1
      src/modules/CameraAnimation/CamAniEditor.js
  9. 397 519
      src/modules/CameraAnimation/CameraAnimation.js
  10. 0 314
      src/modules/Images360/DepthImageSampler.js
  11. 264 2919
      src/modules/Images360/Images360.js
  12. 0 746
      src/modules/Images360/Panorama.js
  13. 0 1198
      src/modules/Images360/tile/PanoRenderer.js
  14. 0 171
      src/modules/Images360/tile/QualityManager.js
  15. 0 513
      src/modules/Images360/tile/TileDownloader.js
  16. 0 395
      src/modules/Images360/tile/TilePrioritizer.js
  17. 0 168
      src/modules/Images360/tile/TileTree.js
  18. 0 283
      src/modules/Images360/tile/TileUtils.js
  19. 0 253
      src/modules/Particles/ParticleEditor.js
  20. 0 343
      src/modules/clipModel/Clip.js
  21. 0 391
      src/modules/datasetAlignment/Alignment.js
  22. 0 616
      src/modules/mergeModel/MergeEditor.js
  23. 0 1227
      src/modules/panoEdit/panoEditor.js
  24. 0 653
      src/modules/route/RouteGuider.js
  25. 0 879
      src/modules/siteModel/BuildingBox.js
  26. 0 1280
      src/modules/siteModel/SiteModel.js
  27. 0 121
      src/objects/Axis.js
  28. 0 141
      src/objects/InfiniteGridHelper.js
  29. 0 84
      src/objects/Label.js
  30. 0 350
      src/objects/Magnifier.js
  31. 0 271
      src/objects/Reticule.js
  32. 0 166
      src/objects/Sprite.js
  33. 0 161
      src/objects/Tag.js
  34. 0 177
      src/objects/TextSprite.js
  35. 0 36
      src/objects/fireParticle/Tween.js
  36. 0 475
      src/objects/fireParticle/explode/ExplodeParticle.js
  37. 0 57
      src/objects/fireParticle/explode/Particle.js
  38. 0 18
      src/objects/fireParticle/explode/Util.js
  39. 0 4
      src/objects/fireParticle/explode/const.js
  40. 0 40
      src/objects/fireParticle/explode/shader.js
  41. 0 274
      src/objects/fireParticle/fire/FireParticle.js
  42. 0 63
      src/objects/fireParticle/fire/shader.js
  43. 0 57
      src/objects/fireParticle/smoke/Particle.js
  44. 0 594
      src/objects/fireParticle/smoke/SmokeParticle.js
  45. 0 44
      src/objects/fireParticle/smoke/shader.js
  46. 0 109
      src/objects/tool/AnnotationTool.js
  47. 0 37
      src/objects/tool/Box3Helper.js
  48. 0 290
      src/objects/tool/ClipVolume.js
  49. 0 185
      src/objects/tool/ClippingTool.js
  50. 0 297
      src/objects/tool/Compass.js
  51. 0 229
      src/objects/tool/CurveCtrl.js
  52. 0 78
      src/objects/tool/HandleSprite.js
  53. 0 155
      src/objects/tool/HandleSvg.js
  54. 0 1245
      src/objects/tool/Measure.js
  55. 0 646
      src/objects/tool/MeasuringTool.js
  56. 0 66
      src/objects/tool/PolygonClipVolume.js
  57. 0 344
      src/objects/tool/Profile.js
  58. 0 132
      src/objects/tool/ProfileTool.js
  59. 0 239
      src/objects/tool/ScreenBoxSelectTool.js
  60. 0 78
      src/objects/tool/SpotLightHelper.js
  61. 0 95
      src/objects/tool/TagTool.js
  62. 0 1981
      src/objects/tool/TransformControls.js
  63. 0 910
      src/objects/tool/TransformationTool.js
  64. 0 313
      src/objects/tool/Volume.js
  65. 0 147
      src/objects/tool/VolumeTool.js
  66. 0 723
      src/objects/tool/ctrlPolygon.js
  67. 0 347
      src/objects/tool/mapClipBox.js
  68. 0 449
      src/settings.js
  69. 0 897
      src/start.js
  70. 0 301
      src/utils/Common.js
  71. 0 115
      src/utils/CursorDeal.js
  72. 0 401
      src/utils/DrawUtil.js
  73. 0 47
      src/utils/History.js
  74. 0 315
      src/utils/MathLight.js
  75. 0 192
      src/utils/SplitScreen.js
  76. 0 342
      src/utils/SplitScreen4Views.js
  77. 0 393
      src/utils/UnitConvert.js
  78. 0 367
      src/utils/browser.js
  79. 0 19
      src/utils/cameraLight.js
  80. 0 608
      src/utils/math.js
  81. 0 879
      src/utils/searchRings.js
  82. 0 486
      src/utils/transitions.js
  83. 28 14
      src/viewer/LoadProject.js
  84. 15 105
      src/viewer/Scene.js
  85. 0 91
      src/viewer/Viewport.js
  86. 0 353
      src/viewer/viewerBase.js

+ 2 - 21
src/Features.js

@@ -1,6 +1,3 @@
-import browser from './utils/browser.js'
-
-
 
 let ftCanvas = document.createElement('canvas');
 
@@ -70,23 +67,6 @@ export const Features = (function () {
 			}
 
 		},
-        //add:
-        EXT_DEPTH:{
-            isSupported: function () { 
-                if(browser.detectIOS()){
-                    let {major,minor,patch} = browser.iosVersion()
-                    if(major == 15 && minor == 4 && patch == 1){
-                        console.warn('检测到是ios15.4.1, 关闭EXT_frag_depth')//该版本ext_depth有问题,导致clear错乱。没有解决办法先关闭。
-                        return false
-                    }
-                }
-
-                return  gl.getExtension('EXT_frag_depth'); //shader中的GL_EXT_frag_depth需要判断一下detectIOS吗。。
-            }
-        },
-        
-         
-        
 		//WEBGL2: {
 		//	isSupported: function(){
 		//		return gl instanceof WebGL2RenderingContext;
@@ -94,4 +74,5 @@ export const Features = (function () {
 		//},
 		precision: precision
 	};
-}());
+}());
+

File diff suppressed because it is too large
+ 50 - 1063
src/PointCloudOctree.js


+ 10 - 11
src/Potree.js

@@ -1,5 +1,5 @@
-												export {config, settings} from "./settings.js";
-												export * from "./start.js";
+    
+   
 export * from "./Actions.js";
 export * from "./AnimationPath.js";
 export * from "./Annotation.js";
@@ -76,8 +76,8 @@ export * from "./utils/TransformationTool.js";
 export * from "./utils/Volume.js";
 export * from "./utils/VolumeTool.js";
 export * from "./utils/Compass.js";
-//export * from "./viewer/viewer.js";
-													export * from "./custom/viewer.js";
+export * from "./viewer/viewer.js";
+											 
 export * from "./viewer/Scene.js";
 export * from "./viewer/HierarchicalSlider.js";
 
@@ -92,8 +92,7 @@ export {FirstPersonControls} from "./navigation/FirstPersonControls.js";
 export {EarthControls} from "./navigation/EarthControls.js";
 export {DeviceOrientationControls} from "./navigation/DeviceOrientationControls.js";
 export {VRControls} from "./navigation/VRControls.js";
-												//add:
-												export {Alignment} from "./modules/datasetAlignment/Alignment.js";
+												 
 import "./extensions/OrthographicCamera.js";
 import "./extensions/PerspectiveCamera.js";
 import "./extensions/Ray.js";
@@ -102,7 +101,7 @@ import {LRU} from "./LRU.js";
 import {OctreeLoader} from "./modules/loader/2.0/OctreeLoader.js";
 import {POCLoader} from "./loader/POCLoader.js";
 import {EptLoader} from "./loader/EptLoader.js";
-import {PointCloudOctree} from "./PointCloudOctree.js";
+import {ExtendPointCloudOctree} from "./ExtendPointCloudOctree.js";
 												//import {ExtendPointCloudOctree} from "./custom/ExtendPointCloudOctree.js";
 import {WorkerPool} from "./WorkerPool.js";
 
@@ -347,7 +346,7 @@ export function loadPointCloud(path, name, sceneCode, timeStamp, callback, onErr
 					console.error(new Error(`failed to load point cloud from URL: ${path}`));
 				}
 				else {
-					let pointcloud = new PointCloudOctree(geometry);
+					let pointcloud = new ExtendPointCloudOctree(geometry);
 					//loaded(pointcloud);
 					resolve({type: 'pointcloud_loaded', pointcloud: pointcloud});
 				}
@@ -359,7 +358,7 @@ export function loadPointCloud(path, name, sceneCode, timeStamp, callback, onErr
 					console.error(new Error(`failed to load point cloud from URL: ${path}`));
                     onError && onError()
 				} else {
-					let pointcloud = new PointCloudOctree(geometry);
+					let pointcloud = new ExtendPointCloudOctree(geometry);
 					// loaded(pointcloud);
 					resolve({type: 'pointcloud_loaded', pointcloud: pointcloud});
 				}
@@ -371,7 +370,7 @@ export function loadPointCloud(path, name, sceneCode, timeStamp, callback, onErr
 				if(!geometry){
 					console.error(new Error(`failed to load point cloud from URL: ${path}`));
 				}else{
-					let pointcloud = new PointCloudOctree(geometry);
+					let pointcloud = new ExtendPointCloudOctree(geometry);
 
 					let aPosition = pointcloud.getAttribute("position");
 
@@ -391,7 +390,7 @@ export function loadPointCloud(path, name, sceneCode, timeStamp, callback, onErr
 					//callback({type: 'loading_failed'});
 					console.error(new Error(`failed to load point cloud from URL: ${path}`));
 				} else {
-					let pointcloud = new PointCloudOctree(geometry);
+					let pointcloud = new ExtendPointCloudOctree(geometry);
 					// loaded(pointcloud);
 					resolve({type: 'pointcloud_loaded', pointcloud: pointcloud});
 				}

+ 27 - 0
src/custom/note.txt

@@ -1,3 +1,30 @@
+
+主文件:start.js
+
+
+start.js可访问全局变量Potree,引用当前目录的其他文件(都是新增的),并修改Potree。
+
+start.js除了通过引用shim文件来修改Potree, 也可在此文件修改,更多是执行加载点云等程序。
+
+
+
+
+
+----
+因为viewer太复杂了就去掉了所有和sidebar有关的代码。也就是说不支持非official的情况。需要用这个测试的需要换分支
+
+
+
+
+
+
+
+
+
+
+
+
+===============================
 libs/stats.js 这个文件夹里的内容不在这个工程里
 libs/three.js 这个文件夹里的内容基本上都改过,但是暂时不管,先处理potree
 libs/three.js/build/three.module.js   

+ 776 - 2
src/custom/potree.shim.js

@@ -3,9 +3,12 @@
 // }
 import * as THREE from "../../libs/three.js/build/three.module.js";
 import math from "../utils/math.js";
+import browser from "../utils/browser.js";
+ 
 import {Utils} from "../utils.js";
 import {BinaryLoader} from "../loader/BinaryLoader.js";
-// import {Features} from "../Features.js";
+import {Features} from "../Features.js";
+
 import {PointAttribute,PointAttributeTypes} from "../loader/PointAttributes.js";
 import {ProfileWindow} from "../viewer/profile.js";
 import {XHRFactory} from "../XHRFactory.js";
@@ -13,6 +16,125 @@ import {ClipTask, ClipMethod} from "../defines.js";
 import {Box3Helper} from "../utils/Box3Helper.js";
 import {KeyCodes} from "../KeyCodes.js";
 
+
+{//defines:
+    Potree.defines = {}
+    Potree.defines.Buttons = {// MouseEvent.buttons
+        //buttons,设置按下了鼠标哪些键,是一个3个比特位的二进制值,默认为0。1表示按下主键(通常是左键),2表示按下次要键(通常是右键),4表示按下辅助键(通常是中间的键)。
+        NONE:0,//add
+        
+        LEFT: 0b0001,
+        RIGHT: 0b0010,
+        MIDDLE: 0b0100
+    };
+    /*  如果访问的是button, 用THREE.MOUSE来判断:
+        button,设置按下了哪一个鼠标按键,默认为0。-1表示没有按键,0表示按下主键(通常是左键),1表示按下辅助键(通常是中间的键),2表示按下次要键(通常是右键)
+     */
+         
+    
+
+    /////////// add ////////////////////////////////// 
+    Potree.defines.GLCubeFaces = {
+        GL_TEXTURE_CUBE_MAP_POSITIVE_X: 0,
+        GL_TEXTURE_CUBE_MAP_NEGATIVE_X: 1,
+        GL_TEXTURE_CUBE_MAP_POSITIVE_Y: 2,
+        GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: 3,
+        GL_TEXTURE_CUBE_MAP_POSITIVE_Z: 4,
+        GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: 5
+    };
+
+
+    Potree.defines.PanoSizeClass = {
+        BASE: 1,
+        STANDARD: 2,
+        HIGH: 3,
+        ULTRAHIGH: 4
+    };
+
+    Potree.defines.PanoRendererEvents = {
+        PanoRenderComplete: "panorama.render.complete",
+        TileRenderFailure: "panorama.tile.render.failed",
+        TileRenderSuccess: "panorama.tile.render.success",
+        TileUploadAttempted: "panorama.tile.upload.attempted",
+        UploadAttemptedForAllTiles: "panorama.upload.attempted.all.tiles",
+        ZoomLevelRenderStarted: "panorama.zoom.render.started"
+    };
+
+    Potree.defines.SceneRendererEvents = {
+        ContextCreated: "scene-renderer-context-created",
+        AfterRender: "after-render",
+        MemoryUsageUpdated: "scene-renderer-memory-usage-updated"
+    };
+
+
+    Potree.defines.TileDownloaderEvents = {
+        TileDownloadSuccess: "tiledownloader.download.success",
+        TileDownloadFailure: "tiledownloader.download.failure",
+        PanoDownloadComplete: "tiledownloader.pano.download.complete"
+    };
+
+    Potree.defines.Vectors = {
+        UP: new THREE.Vector3(0,1,0),
+        DOWN: new THREE.Vector3(0,-1,0),
+        LEFT: new THREE.Vector3(-1,0,0),
+        RIGHT: new THREE.Vector3(1,0,0),
+        FORWARD: new THREE.Vector3(0,0,-1),
+        BACK: new THREE.Vector3(0,0,1)
+    };
+    /* var Vectors2 = {}
+    for(var i in Vectors){
+        Vectors2[i] = math.convertVector.YupToZup(Vectors[i])  
+    }
+     */
+
+
+    Potree.defines.DownloadStatus = Object.freeze({
+        None: 0,
+        Queued: 1,
+        ForceQueued: 2,
+        Downloading: 3,
+        Downloaded: 4,
+        DownloadFailed: 5
+    });
+    Potree.defines.ModelManagerEvents = {
+        ModelAdded: "model-added",
+        ActiveModelChanged: "active-model-changed"
+    };
+
+    Potree.defines.PanoramaEvents = {
+
+        Enter: 'panorama.enter',
+        Exit: 'panorama.exit',
+
+        LoadComplete: "panorama.load.complete",
+        LoadFailed: "panorama.load.failed",
+        TileLoaded: "panorama.tile.loaded",
+        VideoRendered: "panorama.video.rendered"
+    };
+ 
+    
+}
+
+
+
+{//Features
+    Potree.Features.EXT_DEPTH = {
+        isSupported: function (gl) { 
+            if(browser.detectIOS()){
+                let {major,minor,patch} = browser.iosVersion()
+                if(major == 15 && minor == 4 && patch == 1){
+                    console.warn('检测到是ios15.4.1, 关闭EXT_frag_depth')//该版本ext_depth有问题,导致clear错乱。没有解决办法先关闭。
+                    return false
+                }
+            }
+
+            return  gl.getExtension('EXT_frag_depth'); //shader中的GL_EXT_frag_depth需要判断一下detectIOS吗。。
+        }
+    },
+    
+}
+
+
 Utils.loadSkybox = function(path) {
     let parent = new THREE.Object3D("skybox_root");
 
@@ -992,4 +1114,656 @@ Potree.updateVisibility = function(pointclouds, camera, areaSize){
 	};
 };
 
-KeyCodes.BACKSPACE = 8
+KeyCodes.BACKSPACE = 8
+
+
+ 
+class PointCloudOctree extends Potree.PointCloudOctree{
+    constructor(){
+        
+        super()
+        
+        
+        this.boundingBox = this.pcoGeometry.tightBoundingBox//this.pcoGeometry.boundingBox;  //boundingBox是正方体,所以换掉
+		this.boundingSphere = this.boundingBox.getBoundingSphere(new THREE.Sphere());
+        this.nodeMaxLevel = 0;//add
+        this.maxLevel = Infinity;
+        this.temp = { sizeFitToLevel:{}, opacity:{}}//add
+        //add 
+        
+        this.panos = []
+        this.matrixAutoUpdate = false   //最好禁止updateMatrix  直接使用matrixWorld
+        this.orientationUser = 0  
+        this.translateUser = new THREE.Vector3;
+        
+        this.rotateMatrix = new THREE.Matrix4;
+        this.transformMatrix = new THREE.Matrix4;// 数据集的变化矩阵
+        this.transformInvMatrix = new THREE.Matrix4; 
+        this.rotateInvMatrix = new THREE.Matrix4; 
+        
+        
+        this.nodeMaxLevelPredict = this.predictNodeMaxLevel()//预测maxNodeLevel  
+        this.testMaxNodeCount = this.testMaxNodeCount2 = 0
+        
+        this.material.spacing = this.pcoGeometry.spacing;//初始化一下 以便于设置pointsize
+        this._visible = true;
+        this.pcoGeometry.addEventListener('updateNodeMaxLevel', this.updateNodeMaxLevel.bind(this))
+        this.isPointcloud = true    //add
+    }
+    
+    /* 
+    
+    注释:node的level从最大的box 0开始。
+    且加载任意一个node必定也会加载它的所有祖先。(如visibleNodes中有一个level为4,则一定有3,2,1,0) 
+    visibleNodes就是所有可见的node,比如:
+    如果相机在0这个位置朝下,这时候的visibleNodes中只有一个level为0的node;
+    而如果朝上看,上方的几个node如果在视野中占据足够大的位置的话,就会加载。
+    如果相机在2这个位置朝上,这时候的visibleNodes中所包含的level为: 0,1,2
+    
+    ________________
+    |   |   |       |
+    |__2|   |       |
+    |     1 |   1   |
+    |_______|_______|
+    |               |    
+    |               |    
+    |      0        |    
+    |_______________|
+    
+    查看box可在potree中开启
+     */
+     
+    updateNodeMaxLevel(e){//目前点云包含node的最高level  
+        var level = Math.max(e.level, this.nodeMaxLevel)
+        if(level != this.nodeMaxLevel){
+            this.nodeMaxLevel = level 
+            //viewer.dispatchEvent({type:'updateNodeMaxLevel', pointcloud: this, nodeMaxLevel:level}) 
+             
+            //console.log('updateNodeMaxLevel ' + this.dataset_id + " : "+ this.nodeMaxLevel)                
+              
+            this.setPointLevel()//重新计算
+             
+            if(!Potree.settings.sizeFitToLevel){
+                this.changePointSize() 
+            }   
+        }
+    }//注:在没有加载到真实的 nodeMaxLevel之前,点云会显示得偏大
+    , 
+     
+     
+   //panoEdit时比预测值小很多?
+     
+    testMaxNodeLevel(){//手动使maxLevel达到最高,从而迫使updateNodeMaxLevel。  因为Potree.settings.pointDensity 不为 'high'时,maxLevel不是所加载的最高,就很容易加载不出下一个层级,导致无法知道nodeMaxLevel
+        if(this.testMaxNodeLevelDone ) return
+        //if(this.nodeMaxLevel > this.nodeMaxLevelPredict.min  )return 
+        
+        
+        if( this.nodeMaxLevel==0 )return true
+        if( !viewer.atDatasets.includes(this))return true //否则老远就count++
+        
+        let levels = this.visibleNodes.map(e=>e.getLevel())
+        let actMaxLevel = Math.max.apply(null, levels) //实际加载到的最高的node level
+        if(actMaxLevel <  this.maxLevel)return true// 还没加载到能加载到的最高。  但在细节设置较低时,排除作用微弱。
+        
+         
+        //尝试加载出更高级的level 
+        let old = this.maxLevel
+        this.maxLevel = 12;
+        //var visibleNodes1 = this.visibleNodes.map(e=>e.getLevel())
+        //console.log('visibleNodes1',visibleNodes1)
+        Potree.updatePointClouds([this],  viewer.scene.getActiveCamera(), viewer.mainViewport.resolution );
+        //不在camera可视范围内还是加载不出来。即使临时修改位置
+        
+        
+        var visibleNodes2 = this.visibleNodes.map(e=>e.getLevel())
+        //console.log('visibleNodes2',visibleNodes2) 
+        this.maxLevel = old;
+        
+        
+        
+        this.testMaxNodeCount ++
+        if(this.testMaxNodeCount > 500){
+            console.log('testMaxNodeLevel次数超出,强制结束:',this.dataset_id,  this.nodeMaxLevel,  this.nodeMaxLevelPredict.min) 
+            this.testMaxNodeLevelDone = 'moreThanMaxCount'
+            return; //在可以看见点云的情况下,超时,有可能是预测的max是错的    
+        }
+        if(this.nodeMaxLevel < this.nodeMaxLevelPredict.min) return  true //仍需要继续testMaxNodeLevel
+        
+        this.testMaxNodeCount2 ++; // 已经> this.nodeMaxLevelPredict.min 后,开始计数。因为min可能低于真实nodeMaxLevel所以要再试几次
+        
+        /* if(this.name == 'SS-t-CWmVgzP4XU'){
+            console.log('SS-t-CWmVgzP4XU count++')
+        } */
+        
+        if(this.testMaxNodeCount2 < 50)  return  true //再试几次 ( 主要是细节调得低时需要多测几次才加载到
+        this.testMaxNodeLevelDone = true
+        
+        
+           
+         
+        
+    }       
+    , 
+     
+     
+     
+     
+    
+    setPointLevel(){
+        
+        var pointDensity = Potree.settings.pointDensity
+        var config = Potree.config.pointDensity[pointDensity];
+        if(!config)return
+        
+        
+        /* if(this.testingMaxLevel){
+            this.maxLevel = 12;//先加载到最大的直到测试完毕。由于5个level为一组来加载,所以如果写4最高能加载到5,如果写5最高能加载到下一个级别的最高也就是10
+            //console.log('maxLevel: '+e.maxLevel +  ' testingMaxLevel中 '  )                                
+        }else{ */
+            let percent = config.percentByUser && Potree.settings.UserDensityPercent != void 0  ? Potree.settings.UserDensityPercent : config.maxLevelPercent  
+            this.maxLevel = Math.round( percent * this.nodeMaxLevel); 
+            //console.log('maxLevel: '+e.maxLevel +  ',   density : '+Potree.settings.pointDensity,  ",  percent :"+percent);
+            
+            if(Potree.settings.sizeFitToLevel){
+                this.changePointSize() 
+            } 
+            this.changePointOpacity()
+        //}   
+    }
+    
+    //预测可能的nodeMaxLevel:
+    ,
+    predictNodeMaxLevel(){//预测maxNodeLevel。  可能只适用于我们相机拍的点云
+        let spacing = {min:0.005, max:0.014};//最小节的两点间的距离  ,获得方法:spacing / Math.pow(2, nodeMaxLevel)。 目前观测的我们自己拍的这个数值的范围大概是这样
+        let min = Math.log2(this.material.spacing / spacing.max); //有见过最大是0.01368 
+        let max = Math.log2(this.material.spacing / spacing.min); //大部分是 0.006
+        //console.log('predictNodeMaxLevel:', this.name ,  min, max ) 
+    
+    
+        return {min, max}
+    },
+    
+    getHighestNodeSpacing(){
+        return this.material.spacing / Math.pow(2, this.nodeMaxLevel) //前提是这个nodeMaxLevel是准确的
+    },
+    
+    updateMaterial (material, visibleNodes, camera, renderer, resolution) {//改
+		material.fov = camera.fov * (Math.PI / 180);
+		/* material.screenWidth = renderer.domElement.clientWidth;
+		material.screenHeight = renderer.domElement.clientHeight; */
+        material.resolution = resolution
+        
+        
+		//material.spacing = this.pcoGeometry.spacing; // * Math.max(this.scale.x, this.scale.y, this.scale.z);  //应该不需要
+		material.near = camera.near;
+		material.far = camera.far;
+		material.uniforms.octreeSize.value = this.pcoGeometry.boundingBox.getSize(new THREE.Vector3()).x;
+	},
+    
+    pick(viewer, viewport, camera, ray, params = {}){//改
+  
+		let renderer = viewer.renderer;
+		let pRenderer = viewer.pRenderer;
+
+		performance.mark("pick-start");
+
+		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 = getVal(params.pickWindowSize, pickWindowSize_    ); /* 65 */ //拾取像素边长,越小越精准,但点云稀疏的话可能容易出现识别不到的情况。 另外左下侧会有缝隙无法识别到,缝隙大小和这个值有关
+ 
+		let pickOutsideClipRegion = getVal(params.pickOutsideClipRegion, false);
+
+		let size = viewport ? viewport.resolution : renderer.getSize(new THREE.Vector2());
+
+		let width = Math.ceil(getVal(params.width, size.width)); //renderTarget大小。影响识别精度  
+		let height = Math.ceil(getVal(params.height, size.height));
+        
+        let screenshot = ()=>{
+            if(window.testScreen){            
+                let dataUrl = Potree.Utils.renderTargetToDataUrl(pickState.renderTarget, width, height, renderer)
+             
+                Common.downloadFile(dataUrl, 'screenshot.jpg')  //为什么图片上不是只有pickWindowSize区域有颜色??
+                window.testScreen = 0
+            } 
+        }
+        
+      
+
+		let pointSizeType = getVal(params.pointSizeType, this.material.pointSizeType);
+		let pointSize = getVal(params.pointSize, this.material.size);
+
+		let nodes = this.nodesOnRay(this.visibleNodes, ray);
+
+		if (nodes.length === 0) { 
+            
+			return null;
+		}
+        //console.log('nodes.length != 0', this.name)
+		if (!this.pickState) {
+			let scene = new THREE.Scene();
+
+			let material = new Potree.PointCloudMaterial();
+			material.activeAttributeName = "indices";
+
+			let renderTarget = new THREE.WebGLRenderTarget(
+				1, 1,
+				{ minFilter: THREE.LinearFilter,
+					magFilter: THREE.NearestFilter,
+					format: THREE.RGBAFormat }
+			);
+
+			this.pickState = {
+				renderTarget: renderTarget,
+				material: material,
+				scene: scene
+			};
+		};
+
+		let pickState = this.pickState;
+		let pickMaterial = pickState.material;
+
+		{ // update pick material
+			pickMaterial.pointSizeType = pointSizeType;
+			//pickMaterial.shape = this.material.shape;
+			pickMaterial.shape = Potree.PointShape.PARABOLOID;
+
+			pickMaterial.uniforms.uFilterReturnNumberRange.value = this.material.uniforms.uFilterReturnNumberRange.value;
+			pickMaterial.uniforms.uFilterNumberOfReturnsRange.value = this.material.uniforms.uFilterNumberOfReturnsRange.value;
+			pickMaterial.uniforms.uFilterGPSTimeClipRange.value = this.material.uniforms.uFilterGPSTimeClipRange.value;
+			pickMaterial.uniforms.uFilterPointSourceIDClipRange.value = this.material.uniforms.uFilterPointSourceIDClipRange.value;
+
+			pickMaterial.activeAttributeName = "indices";
+
+			pickMaterial.size = pointSize;
+			pickMaterial.uniforms.minSize.value = this.material.uniforms.minSize.value;
+			pickMaterial.uniforms.maxSize.value = this.material.uniforms.maxSize.value;
+			pickMaterial.classification = this.material.classification;
+			pickMaterial.recomputeClassification();
+
+			if(params.pickClipped){
+				pickMaterial.clipBoxes = this.material.clipBoxes;
+				pickMaterial.uniforms.clipBoxes = this.material.uniforms.clipBoxes;
+				if(this.material.clipTask === Potree.ClipTask.HIGHLIGHT){
+					pickMaterial.clipTask = Potree.ClipTask.NONE;
+				}else{
+					pickMaterial.clipTask = this.material.clipTask;
+				}
+				pickMaterial.clipMethod = this.material.clipMethod;
+			}else{
+				pickMaterial.clipBoxes = [];
+			}
+
+			this.updateMaterial(pickMaterial, nodes, camera, renderer, new THREE.Vector2(width, height));
+		}
+
+		pickState.renderTarget.setSize(width, height); //仅绘制屏幕大小的,而不乘以devicePixelRatio
+
+		let pixelPos = new THREE.Vector2(params.x, params.y);
+
+		let gl = renderer.getContext();
+		gl.enable(gl.SCISSOR_TEST);
+		gl.scissor(  //规定渲染范围,只渲染一小块
+			parseInt(pixelPos.x - (pickWindowSize - 1) / 2),
+			parseInt(pixelPos.y - (pickWindowSize - 1) / 2),
+			parseInt(pickWindowSize), parseInt(pickWindowSize));
+
+
+		renderer.state.buffers.depth.setTest(pickMaterial.depthTest);
+		renderer.state.buffers.depth.setMask(pickMaterial.depthWrite);
+		renderer.state.setBlending(THREE.NoBlending);
+
+		{ // RENDER
+			renderer.setRenderTarget(pickState.renderTarget);
+			gl.clearColor(0, 0, 0, 0);
+			renderer.clear(true, true, true);
+
+			let tmp = this.material;
+			this.material = pickMaterial;
+            
+			pRenderer.renderOctree(this, nodes, camera, pickState.renderTarget);
+            screenshot();
+
+
+			this.material = tmp;
+		}
+
+		let clamp = (number, min, max) => Math.min(Math.max(min, number), max);
+
+		let x = parseInt(clamp(pixelPos.x - (pickWindowSize - 1) / 2, 0, width));
+		let y = parseInt(clamp(pixelPos.y - (pickWindowSize - 1) / 2, 0, height));
+		/* let w = parseInt(Math.min(x + pickWindowSize, width) - x);
+		let h = parseInt(Math.min(y + pickWindowSize, height) - y); */
+        
+		let pixelCount = pickWindowSize * pickWindowSize//w * h;
+		let buffer = new Uint8Array(4 * pixelCount);
+        //w<pickWindowSize会报错
+        
+		gl.readPixels(x, y, pickWindowSize, pickWindowSize, gl.RGBA, gl.UNSIGNED_BYTE, buffer);
+
+		renderer.setRenderTarget(null);
+		renderer.state.reset();
+		renderer.setScissorTest(false);
+		gl.disable(gl.SCISSOR_TEST);
+
+		let pixels = buffer;
+		let ibuffer = new Uint32Array(buffer.buffer); //四个数整合成一个
+
+		// find closest hit inside pixelWindow boundaries
+		let min = Number.MAX_VALUE;
+		let hits = [];
+		for (let u = 0; u < pickWindowSize; u++) {
+			for (let v = 0; v < pickWindowSize; v++) {
+				let offset = (u + v * pickWindowSize);
+				let distance = Math.pow(u - (pickWindowSize - 1) / 2, 2) + Math.pow(v - (pickWindowSize - 1) / 2, 2);
+
+				let pcIndex = pixels[4 * offset + 3];//nodes index(第四位)
+				pixels[4 * offset + 3] = 0; //去除nodes index后剩下的是index(前三位)
+				let pIndex = ibuffer[offset]; //index
+
+				if(!(pcIndex === 0 && pIndex === 0) && (pcIndex !== undefined) && (pIndex !== undefined)){
+					let hit = {
+						pIndex: pIndex,
+						pcIndex: pcIndex,
+						distanceToCenter: distance
+					};
+
+					if(params.all){
+						hits.push(hit);
+					}else{
+						if(hits.length > 0){
+							if(distance < hits[0].distanceToCenter){
+								hits[0] = hit;
+							}
+						}else{
+							hits.push(hit);
+						}
+					}
+
+
+				}
+			}
+		}
+
+		
+		// { // DEBUG: show panel with pick image
+		// 	let img = Utils.pixelsArrayToImage(buffer, w, h);
+		// 	let screenshot = img.src;
+		
+		// 	if(!this.debugDIV){
+		// 		this.debugDIV = $(`
+		// 			<div id="pickDebug"
+		// 			style="position: absolute;
+		// 			right: 400px; width: 300px;
+		// 			bottom: 44px; width: 300px;
+		// 			z-index: 1000;
+		// 			"></div>`);
+		// 		$(document.body).append(this.debugDIV);
+		// 	}
+		
+		// 	this.debugDIV.empty();
+		// 	this.debugDIV.append($(`<img src="${screenshot}"
+		// 		style="transform: scaleY(-1); width: 300px"/>`));
+		// 	//$(this.debugWindow.document).append($(`<img src="${screenshot}"/>`));
+		// 	//this.debugWindow.document.write('<img src="'+screenshot+'"/>');
+		// }
+
+
+		for(let hit of hits){
+			let point = {};
+
+			if (!nodes[hit.pcIndex]) {
+				return null;
+			}
+
+			let node = nodes[hit.pcIndex];
+			let pc = node.sceneNode;
+			let geometry = node.geometryNode.geometry;
+
+			for(let attributeName in geometry.attributes){
+				let attribute = geometry.attributes[attributeName];
+
+				if (attributeName === 'position') {
+					let x = attribute.array[3 * hit.pIndex + 0];
+					let y = attribute.array[3 * hit.pIndex + 1];
+					let z = attribute.array[3 * hit.pIndex + 2];
+
+					let position = new THREE.Vector3(x, y, z);
+                    
+					position.applyMatrix4( pc.matrixWorld );
+                    
+					point[attributeName] = position;
+				} else if (attributeName === 'indices') {
+
+				} else {
+
+					let values = attribute.array.slice(attribute.itemSize * hit.pIndex, attribute.itemSize * (hit.pIndex + 1)) ;
+
+					if(attribute.potree){
+						const {scale, offset} = attribute.potree;
+						values = values.map(v => v / scale + offset);
+					}
+
+					point[attributeName] = values;
+
+					//debugger;
+					//if (values.itemSize === 1) {
+					//	point[attribute.name] = values.array[hit.pIndex];
+					//} else {
+					//	let value = [];
+					//	for (let j = 0; j < values.itemSize; j++) {
+					//		value.push(values.array[values.itemSize * hit.pIndex + j]);
+					//	}
+					//	point[attribute.name] = value;
+					//}
+				}
+
+			}
+
+			hit.point = point;
+		}
+
+		performance.mark("pick-end");
+		performance.measure("pick", "pick-start", "pick-end");
+
+		if(params.all){
+			return hits.map(hit => hit.point);
+		}else{
+			if(hits.length === 0){
+				return null;
+			}else{
+				return hits[0].point;
+				//let sorted = hits.sort( (a, b) => a.distanceToCenter - b.distanceToCenter);
+
+				//return sorted[0].point;
+			}
+		}
+
+	},
+
+
+    // 设置点大小
+    changePointSize(num, sizeFitToLevel) {
+ 
+        if(this.material.pointSizeType != PointSizeType.ATTENUATED){
+            return num && (this.material.size = num)
+        }
+        if (num == void 0) {
+            num = this.temp.pointSize
+        } else {
+            this.temp.pointSize = num
+            
+        }
+        num /= (Potree.config.material.realPointSize / Potree.config.material.pointSize) //兼容 
+         
+        
+        
+        
+        num = Math.pow(num, 1.05) * 6 
+        
+        
+        
+        
+        if(sizeFitToLevel || Potree.settings.sizeFitToLevel){//按照点云质量来调整的版本:    近似将pointSizeType换成ADAPTIVE
+            let str = this.temp.pointSize+':'+this.maxLevel+':'+this.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.3)) : 0.1 //低质量的缩小点,因为视觉上看太大了。navvis是不铺满的,我们也留一点缝隙
+
+                this.material.size = base * 3 * num/*  * window.devicePixelRatio */
+                //在t-8BCqxQAr93 会议室 和 t-e2Kb2iU 隧道 两个场景里调节,因为它们的spacing相差较大,观察会议室墙壁的龟裂程度
+                this.temp.sizeFitToLevel[str] = this.material.size
+            }
+        }else{ 
+        
+            let base = 0.007;  //let base = this.material.spacing / Math.pow(2, this.nodeMaxLevel) //点云大小在level为0时设置为spacing,每长一级,大小就除以2
+            //base的数值理论上应该是右侧算出来的,但发现有的场景nodeMaxLevel和nodeMaxLevelPredict差别较大的点云显示也过大,而直接换成固定值反而可以适应所有场景。该固定值来源于 getHighestNodeSpacing 最小值,修改了下。(会不会是我们的相机其实该值是固定的,根据该值算出的spacing才是有误差的? 如果换了相机是否要改值?)
+            this.material.size = base * 5 * num /* * window.devicePixelRatio  */
+        } 
+        
+        
+        //console.log('changePointSize  '  + this.dataset_id + '  , num : ' + num + ' , size : ' + this.material.size, this.material.spacing)
+
+         
+    } , 
+    
+    
+    
+    // 设置点透明度
+    changePointOpacity(num, canMoreThanOne) {
+        //num:0-1   navvis用的是亮度
+        if (num == void 0) {
+            num = this.temp.pointOpacity
+        } else {
+            this.temp.pointOpacity = num
+        }
+        
+        if(Potree.settings.editType == 'merge'){ //not AdditiveBlending
+            return this.material.opacity = num
+        }
+      
+        if (num == 1) {
+            this.material.opacity = 1
+        } else { 
+
+            let str = (Potree.settings.sizeFitToLevel?'sizeFit:':'')+ (canMoreThanOne ? 'canMoreThanOne:':'') +this.temp.pointOpacity+':'+this.maxLevel+':'+this.nodeMaxLevel
+            let value = this.temp.opacity[str]  //储存。防止每次渲染(反复切换density)都要算。
+            if(value){
+                this.material.opacity = value
+            }else{
+                if(Potree.settings.sizeFitToLevel){//按照点云质量来调整的版本:
+                    let base = this.material.spacing / Math.pow(1.4, this.maxLevel) //随着level提高,点云重叠几率增多
+                    let minBase = this.material.spacing / Math.pow(1.4, this.nodeMaxLevel)
+                    let ratio = Math.min(1 / base, 1 / minBase / 3) //ratio为一个能使opacity不大于1 的 乘量,minBase要除以一个数,该数调越大减弱效果越强。level越低opacity和面板越接,level越高效果越弱,以减免过度重叠后的亮度。
+                    this.material.opacity = base * ratio * num
+                    if(!canMoreThanOne){
+                        this.material.opacity = THREE.Math.clamp(this.material.opacity, 0, 0.999) //到1就不透明了(可能出现一段一样)
+                    }
+                }else{
+                    let base = this.material.spacing / Math.pow(1.8, this.maxLevel) 
+                    let minBase = this.material.spacing / Math.pow(1.8, this.nodeMaxLevel)
+                    //console.log(1 / base, 1 / minBase / 6)
+                    let ratio = Math.min(1 / base, 1 / minBase / 6) //ratio为一个能使opacity不大于1 的 乘量,minBase要除以一个数,该数调越大减弱效果越强。level越低opacity和面板越接,level越高效果越弱,以减免过度重叠后的亮度。
+                    this.material.opacity = base * ratio * num
+                    if(!canMoreThanOne){
+                        this.material.opacity = THREE.Math.clamp(this.material.opacity, 0, 0.999) //到1就不透明了(可能出现一段一样)
+                    }
+                }
+                this.temp.opacity[str] = this.material.opacity
+            }
+                
+            //缺点:防止颜色过亮主要是相机离远时,当在漫游点处由于离点云太近,可能会导致高质量点云看起来很暗。
+        }
+        //console.log('changePointOpacity ' + this.dataset_id + ', num : ' + num + ' , opacity : ' + this.material.opacity) //检查是否做到了低质量时num==opacity,中质量opacity稍小于num,高质量更小
+         
+    } 
+    ,
+
+
+    updateBound(){
+        var boundingBox_ = this.pcoGeometry.tightBoundingBox.clone().applyMatrix4(this.matrixWorld)
+        this.bound = boundingBox_
+    },
+    getPanosBound(){
+        if(this.panos.length > 0){
+            let minSize = new THREE.Vector3(1,1,1)
+            this.panosBound = math.getBoundByPoints(this.panos.map(e=>e.position), minSize)
+        }else{
+            this.panosBound = null
+        } 
+    },
+    
+    getUnrotBoundPoint(type){//获取没有旋转的tightBounding的水平四个点
+        //如果alighment支持任意轴旋转,水平面上看到的可能就是六边形了,失去意义,到时候不能用这个。也可以若只绕z旋转, 使用tightBoundingBox,否则bound
+        let bound = this.pcoGeometry.tightBoundingBox 
+
+        if(type == 'all'){
+            return [new THREE.Vector3(bound.min.x, bound.min.y, bound.min.z),
+                new THREE.Vector3(bound.max.x, bound.min.y, bound.min.z),
+                new THREE.Vector3(bound.max.x, bound.max.y,bound.min.z),
+                new THREE.Vector3(bound.min.x, bound.max.y,bound.min.z),
+                new THREE.Vector3(bound.min.x, bound.min.y, bound.max.z),
+                new THREE.Vector3(bound.max.x, bound.min.y, bound.max.z),
+                new THREE.Vector3(bound.max.x, bound.max.y,bound.max.z),
+                new THREE.Vector3(bound.min.x, bound.max.y,bound.max.z),
+            ].map(e=>e.applyMatrix4(this.matrixWorld)) 
+
+        }else 
+            return [new THREE.Vector3(bound.min.x, bound.min.y,0),
+                new THREE.Vector3(bound.max.x, bound.min.y,0),
+                new THREE.Vector3(bound.max.x, bound.max.y,0),
+                new THREE.Vector3(bound.min.x, bound.max.y,0),
+            ].map(e=>e.applyMatrix4(this.matrixWorld)) 
+    } 
+    ,
+    
+    
+    ifContainsPoint(pos){
+        if(!this.bound || !this.bound.containsPoint(pos))return
+        var points = this.getUnrotBoundPoint()
+        return math.isPointInArea(points, null, pos)  
+    } 
+    ,
+    getVolume(){
+        var points = this.getUnrotBoundPoint()
+        var area = Math.abs(math.getArea(points))
+        return area * (this.bound.max.z - this.bound.min.z)
+    }  
+    
+}
+ 
+
+Potree.PointCloudOctree.prototype = PointCloudOctree.prototype
+
+class Scene extends Potree.scene{
+    constructor(){
+        
+        
+        
+        
+    }
+}
+Potree.Scene 
+
+
+
+
+
+    
+ 
+
+
+ 
+
+
+
+
+
+
+

File diff suppressed because it is too large
+ 0 - 5181
src/custom/viewer.js


+ 5 - 121
src/defines.js

@@ -1,6 +1,6 @@
-import * as THREE from "../libs/three.js/build/three.module.js";
+
 import {Enum} from "./Enum.js";
-import math from "./utils/math.js";
+
 
 export const CameraMode = {
 	ORTHOGRAPHIC: 0,
@@ -26,17 +26,11 @@ export const ElevationGradientRepeat = {
 	MIRRORED_REPEAT: 2,
 };
 
-export const Buttons = {// MouseEvent.buttons
-    //buttons,设置按下了鼠标哪些键,是一个3个比特位的二进制值,默认为0。1表示按下主键(通常是左键),2表示按下次要键(通常是右键),4表示按下辅助键(通常是中间的键)。
-	NONE:0,//add
-    
-    LEFT: 0b0001,
+export const MOUSE = {
+	LEFT: 0b0001,
 	RIGHT: 0b0010,
 	MIDDLE: 0b0100
 };
-/*  如果访问的是button, 用THREE.MOUSE来判断:
-    button,设置按下了哪一个鼠标按键,默认为0。-1表示没有按键,0表示按下主键(通常是左键),1表示按下辅助键(通常是中间的键),2表示按下次要键(通常是右键)
- */
 
 export const PointSizeType = {
 	FIXED: 0,
@@ -59,114 +53,4 @@ export const LengthUnits = {
 	METER: {code: 'm', unitspermeter: 1.0},
 	FEET: {code: 'ft', unitspermeter: 3.28084},
 	INCH: {code: '\u2033', unitspermeter: 39.3701}
-};
-
-
-
-/////////// add //////////////////////////////////
-
- 
-
-var GLCubeFaces = {
-    GL_TEXTURE_CUBE_MAP_POSITIVE_X: 0,
-    GL_TEXTURE_CUBE_MAP_NEGATIVE_X: 1,
-    GL_TEXTURE_CUBE_MAP_POSITIVE_Y: 2,
-    GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: 3,
-    GL_TEXTURE_CUBE_MAP_POSITIVE_Z: 4,
-    GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: 5
-};
-
-
-var PanoSizeClass = {
-    BASE: 1,
-    STANDARD: 2,
-    HIGH: 3,
-    ULTRAHIGH: 4
-};
-
-var PanoRendererEvents = {
-    PanoRenderComplete: "panorama.render.complete",
-    TileRenderFailure: "panorama.tile.render.failed",
-    TileRenderSuccess: "panorama.tile.render.success",
-    TileUploadAttempted: "panorama.tile.upload.attempted",
-    UploadAttemptedForAllTiles: "panorama.upload.attempted.all.tiles",
-    ZoomLevelRenderStarted: "panorama.zoom.render.started"
-};
-
-var SceneRendererEvents = {
-    ContextCreated: "scene-renderer-context-created",
-    AfterRender: "after-render",
-    MemoryUsageUpdated: "scene-renderer-memory-usage-updated"
-};
-
-
-var TileDownloaderEvents = {
-    TileDownloadSuccess: "tiledownloader.download.success",
-    TileDownloadFailure: "tiledownloader.download.failure",
-    PanoDownloadComplete: "tiledownloader.pano.download.complete"
-};
-
-var Vectors = {
-    UP: new THREE.Vector3(0,1,0),
-    DOWN: new THREE.Vector3(0,-1,0),
-    LEFT: new THREE.Vector3(-1,0,0),
-    RIGHT: new THREE.Vector3(1,0,0),
-    FORWARD: new THREE.Vector3(0,0,-1),
-    BACK: new THREE.Vector3(0,0,1)
-};
-var Vectors2 = {}
-for(var i in Vectors){
-    Vectors2[i] = math.convertVector.YupToZup(Vectors[i])  
-}
-
-
-
-var DownloadStatus = Object.freeze({
-    None: 0,
-    Queued: 1,
-    ForceQueued: 2,
-    Downloading: 3,
-    Downloaded: 4,
-    DownloadFailed: 5
-});
-var ModelManagerEvents = {
-    ModelAdded: "model-added",
-    ActiveModelChanged: "active-model-changed"
-};
-
-var PanoramaEvents = {
-
-    Enter: 'panorama.enter',
-    Exit: 'panorama.exit',
-
-    LoadComplete: "panorama.load.complete",
-    LoadFailed: "panorama.load.failed",
-    TileLoaded: "panorama.tile.loaded",
-    VideoRendered: "panorama.video.rendered"
-};
- 
-
-
-
-
-export {GLCubeFaces,PanoSizeClass,PanoRendererEvents,SceneRendererEvents,
-TileDownloaderEvents,Vectors,Vectors2,DownloadStatus,ModelManagerEvents, PanoramaEvents,
- 
-
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+};

+ 1 - 1
src/modules/CameraAnimation/CamAniEditor.js

@@ -1,5 +1,5 @@
 import * as THREE from "../../../libs/three.js/build/three.module.js"; 
-import {CameraAnimation} from './CameraAnimation.js'
+import {CameraAnimation} from './CameraAnimationNew.js'
 
 
 

File diff suppressed because it is too large
+ 397 - 519
src/modules/CameraAnimation/CameraAnimation.js


+ 0 - 314
src/modules/Images360/DepthImageSampler.js

@@ -1,314 +0,0 @@
-
-
-import math from "../../utils/math.js";
-
-class DepthImageSampler {
-    
-    constructor(){ 
-        var canvas = document.createElement("canvas");
-        this.canvas = canvas
-        this.context = canvas.getContext("2d")  
-        
-        
-        /* document.getElementsByTagName('body')[0].appendChild(canvas);
-        canvas.style.position = 'fixed';
-        canvas.style.width = '1024px';
-        canvas.style.top = canvas.style.left = 0
-        canvas.style['z-index'] = 100
-         */
-        
-    }
- 
-     
-    changeImg(img){
-        if(this.img == img)return
-        this.canvas.width = img.width 
-        this.canvas.height = img.height 
-        this.context.drawImage(img, 0, 0)
-        this.img = img
-    } 
-    
-     
-    getDepth(UVx, UVy) {//根据图片像素获取深度值 
-        var x = Math.round(UVx * (this.canvas.width - 1))
-          , y = Math.round(UVy * (this.canvas.height - 1));
-        if (!(x < 0 || y < 0 || x >= this.width || y >= this.height)) {
-            var r = this.context.getImageData(x, y, 1, 1).data;
-            //console.log('color', r, x,y)
-            return r[1] + r[0] / 256
-        }
-    }   
-    
-    
-    sample( intersect, currentPano, onlyPos ) {//通过和skybox的intersect得到真实的intersect的位置
-        if(!intersect)return
-        let location = new THREE.Vector3
-        let normal
-        currentPano = currentPano || viewer.images360.currentPano
-         
-        if(currentPano != this.currentPano){
-            if(!currentPano.depthTex/*  || !currentPano.depthTex.image  */) return //未加载
-            this.changeImg(currentPano.depthTex.image)
-            this.currentPano = currentPano
-        }
-        
-        let origin = currentPano.position
-        let dir = intersect.dir || new THREE.Vector3().subVectors(intersect.point, origin).normalize()
-        //var uv = intersect.uv 
-        //let dirInPano = math.getNormalDir(dir, currentPano)//转化为考虑漫游点旋转的方向
-        
-        let dirInPano = dir.clone().applyMatrix4(currentPano.panoMatrix2Inverse).normalize(); //转化为考虑漫游点旋转的方向
-        let uv = math.getUVfromDir(dirInPano)//转化为uv
-        
-        let distance = this.getDepth(uv.x, uv.y);
-        //console.log('depth', depth,  uv.y)
-        if (!distance){
-            if(uv.y > 0.75){//漫游点底部识别不到的区域,给一个地板高度
-                //let height = origin.distanceTo(currentPano.floorPosition); 
-                const margin =  0.1
-                distance = (currentPano.floorPosition.z - origin.z - margin) / dir.z
-                location.copy(dir).multiplyScalar(distance).add(origin);
-                let normal = new THREE.Vector3(0,0,1)
-                
-                return {location, normal, distance} 
-            }
-            else return !1;  //应该是天空或模型外 , 因为很少有漫游点的地方还拍不到地板
-        }  
-        
-        //this.mainDepth = depth
-       
-        location.copy(dir).multiplyScalar(distance).add(origin);
-        
-        if(!onlyPos){
-           
-           var pL = this.getNearbyPoint(origin, uv, -1, 0)
-          , pR = this.getNearbyPoint(origin, uv,  1, 0)
-          , pB = this.getNearbyPoint(origin, uv,  0, -1)
-          , pT = this.getNearbyPoint(origin, uv,  0, 1);
-           
-            normal = this.planeFit(dir,location, pL,pR,pB,pT  )  
-        }
- 
-          
-        /* if(normal.x != normal.x ){ 
-            console.log('NAN',  normal)
-            var pL = this.getNearbyPoint(origin, uv, -1, 0)
-          , pR = this.getNearbyPoint(origin, uv,  1, 0)
-          , pB = this.getNearbyPoint(origin, uv,  0, -1)
-          , pT = this.getNearbyPoint(origin, uv,  0, 1);
-           
-        } */
-        
-        //console.log('normal',normal)
-          
-        return {location, normal,  distance} 
-    }
-    
-    
-    getNearbyPoint(   origin, uv, x, y) { //获取附近的若干像素距离的点
-        let uv2 = uv.clone()  
-        uv2.x += x/(this.canvas.width-1); 
-        uv2.x = this.clampUV(uv2.x)
-         
-        uv2.y += y/(this.canvas.height-1);
-        uv2.y = this.clampUV(uv2.y)
-        
-        /* if(uv2.x < 0 || uv2.y < 0 || uv2.x > 1 || uv2.y > 1){
-            console.log('will nan')
-        } */
-        
-        let dir = math.getDirFromUV(uv2)//从uv获取到方向
-        dir.applyMatrix4(viewer.images360.currentPano.panoMatrix2)
-        let depth = this.getDepth(uv2.x, uv2.y);
-        /* if(Math.abs(depth - this.mainDepth) > 0.3){
-            console.log('Math.abs(depth - this.mainDepth) > 0.3')
-        } */
-        
-        //let dir = new THREE.Vector3().subVectors(intersect.point, origin).normalize()
-        let position = new THREE.Vector3().copy(dir).multiplyScalar(depth).add(origin);
-        
-        //console.log('getNearbyPoint', uv2, depth, dir, position )
-        
-        return position
-    } 
-
-    clampUV(v){
-        return (v + 1) % 1;   //  使输出在 0-1
-    }
-    
-    planeFit(dir, position, pL,pR,pB,pT ) {//求平均法线
-        let normal = new THREE.Vector3
-         
-        
-        let plane = new THREE.Plane; 
-        function addNormal(p1, p2) {//根据临接的四个点,分别求法线,然后法线相加能得到平均法线
-            if(!p1 || !p2)return
-            plane.setFromCoplanarPoints(position, p1, p2)
-            
-            //console.log('normalSub', plane.normal)
-            
-            normal.addScaledVector(plane.normal,  dir.dot(plane.normal) < 0 ? 1 : -1)//根据面的朝向判断加还是减
-        }
-        addNormal(pL, pB) 
-        addNormal(pL, pT) 
-        addNormal(pR, pB) 
-        addNormal(pR, pT) 
-         
-        if(0 !== normal.x || 0 !== normal.y || 0 !== normal.z){ 
-            normal.normalize()
-            //console.log(normal)
-            return normal
-        }
-         
-         
-        /* 四个面拼成一个菱形 */        
-          
-    } 
-      
-    
-    /* makeUvToPosMap(intersect, matrix1, vec1, vec2) {
-        var o = intersect.object.geometry
-          , a = o.attributes.position.array
-          , s = new THREE.Vector3(a[3 * intersect.face.a],a[3 * intersect.face.a + 1],a[3 * intersect.face.a + 2]).applyMatrix4(intersect.object.matrixWorld)
-          , c = new THREE.Vector3(a[3 * intersect.face.b],a[3 * intersect.face.b + 1],a[3 * intersect.face.b + 2]).applyMatrix4(intersect.object.matrixWorld)
-          , l = new THREE.Vector3(a[3 * intersect.face.c],a[3 * intersect.face.c + 1],a[3 * intersect.face.c + 2]).applyMatrix4(intersect.object.matrixWorld);
-        vec1.subVectors(s, c),
-        vec2.subVectors(l, c);
-        var u = o.attributes.uv.array
-          , d = new THREE.Vector2(u[2 * intersect.face.a],u[2 * intersect.face.a + 1])
-          , p = new THREE.Vector2(u[2 * intersect.face.b],u[2 * intersect.face.b + 1])
-          , h = new THREE.Vector2(u[2 * intersect.face.c],u[2 * intersect.face.c + 1])
-          , f = d.sub(p)
-          , g = h.sub(p);
-        matrix1.set(f.x, g.x, 0, f.y, g.y, 0, 0, 0, 1),
-        matrix1.getInverse(matrix1)
-    } */
-    
-
-  
-    /* getNearbyPoint(  point, origin, uv, o, a, s, x, y) {
-        var add = new THREE.Vector3(x, y , 0 ) 
-          , depth = this.getDepth(uv.x + add.x, uv.y + add.y  );
-           
-        if (void 0 !== depth) {
-            var f = add.applyMatrix3(o);
-            return (new THREE.Vector3).addScaledVector(a, f.x).addScaledVector(s, f.y).add(point).sub(origin).normalize().multiplyScalar(depth).add(origin)
-        }
-    } */
-    
-    
-    
-}
-
-/* 
-    注:
-    
-    当前测试的图不太对,三个通道都一样了,所以几乎是整数的depth。法线也几乎都朝向相机
-
-    由于有时候获取intersect需要知道是哪个点云,所以还是不能用这个。如加测量线。
-
- */
-
-export default DepthImageSampler
-
-
-    /* var i = n(4)
-      , r = function() {
-        function t(t) {
-            
-        }
-        return t.prototype.getDepth = function(t, e) {
-            var n = Math.round(t)
-              , i = Math.round(e);
-            if (!(n < 0 || i < 0 || n >= this.width || i >= this.height)) {
-                var r = this.context.getImageData(n, i, 1, 1).data;
-                return r[1] + r[0] / 256
-            }
-        }
-        ,
-        Object.defineProperty(t.prototype, "width", {
-            get: function() {
-                return this.context.canvas.width
-            },
-            enumerable: !0,
-            configurable: !0
-        }),
-        Object.defineProperty(t.prototype, "height", {
-            get: function() {
-                return this.context.canvas.height
-            },
-            enumerable: !0,
-            configurable: !0
-        }),
-        t
-    }();
-    e.CanvasDepthImage = r;
-    var o = function() {
-        function t() {}
-        return t.sample = function(e, n, r, o, a) {
-            var s = n.uv
-              , c = s.x * (e.width - 1)
-              , l = (1 - s.y) * (e.height - 1)
-              , u = e.getDepth(c, l);
-            if (!u)
-                return !1;
-            o.copy(n.point).sub(r).normalize().multiplyScalar(u).add(r);
-            var d = new i.Matrix3
-              , p = new i.Vector3
-              , h = new i.Vector3;
-            t.makeUvToPosMap(n, d, p, h);
-            var f = this.getNearbyPoint(e, n.point, r, s, d, p, h, -1, 0)
-              , g = this.getNearbyPoint(e, n.point, r, s, d, p, h, 1, 0)
-              , m = this.getNearbyPoint(e, n.point, r, s, d, p, h, 0, -1)
-              , v = this.getNearbyPoint(e, n.point, r, s, d, p, h, 0, 1);
-            return this.planeFit(o, r, f, g, m, v, a)
-        }
-        ,
-        t.makeUvToPosMap = function(t, e, n, r) {
-            var o = t.object.geometry
-              , a = o.attributes.position.array
-              , s = new i.Vector3(a[3 * t.face.a],a[3 * t.face.a + 1],a[3 * t.face.a + 2]).applyMatrix4(t.object.matrixWorld)
-              , c = new i.Vector3(a[3 * t.face.b],a[3 * t.face.b + 1],a[3 * t.face.b + 2]).applyMatrix4(t.object.matrixWorld)
-              , l = new i.Vector3(a[3 * t.face.c],a[3 * t.face.c + 1],a[3 * t.face.c + 2]).applyMatrix4(t.object.matrixWorld);
-            n.subVectors(s, c),
-            r.subVectors(l, c);
-            var u = o.attributes.uv.array
-              , d = new i.Vector2(u[2 * t.face.a],u[2 * t.face.a + 1])
-              , p = new i.Vector2(u[2 * t.face.b],u[2 * t.face.b + 1])
-              , h = new i.Vector2(u[2 * t.face.c],u[2 * t.face.c + 1])
-              , f = d.sub(p)
-              , g = h.sub(p);
-            e.set(f.x, g.x, 0, f.y, g.y, 0, 0, 0, 1),
-            e.getInverse(e)
-        }
-        ,
-        t.getNearbyPoint = function(t, e, n, r, o, a, s, c, l) {
-            var u = new i.Vector3(c / (t.width - 1),l / (t.height - 1))
-              , d = (r.x + u.x) * (t.width - 1)
-              , p = (1 - (r.y + u.y)) * (t.height - 1)
-              , h = t.getDepth(d, p);
-            if (void 0 !== h) {
-                var f = u.applyMatrix3(o);
-                return (new i.Vector3).addScaledVector(a, f.x).addScaledVector(s, f.y).add(e).sub(n).normalize().multiplyScalar(h).add(n)
-            }
-        }
-        ,
-        t.planeFit = function(t, e, n, r, o, a, s) {
-            s.set(0, 0, 0);
-            var c = t.clone().sub(e)
-              , l = new i.Plane;
-            function u(e, n) {
-                e && n && (l.setFromCoplanarPoints(t, e, n),
-                s.addScaledVector(l.normal, c.dot(l.normal) < 0 ? 1 : -1))
-            }
-            return u(n, o),
-            u(n, a),
-            u(r, o),
-            u(r, a),
-            (0 !== s.x || 0 !== s.y || 0 !== s.z) && (s.normalize(),
-            !0)
-        }
-        ,
-        t
-    }();
-    */

File diff suppressed because it is too large
+ 264 - 2919
src/modules/Images360/Images360.js


+ 0 - 746
src/modules/Images360/Panorama.js

@@ -1,746 +0,0 @@
-import * as THREE from "../../../libs/three.js/build/three.module.js";
-import {transitions, easing, lerp} from '../../utils/transitions.js'
-import TileUtils from './tile/TileUtils.js'
-import { PanoRendererEvents, PanoramaEvents, PanoSizeClass} from '../../defines.js'
-import math from '../../utils/math.js' 
-import {TextSprite} from '../../objects/TextSprite.js'
-import DepthBasicMaterial from "../../materials/DepthBasicMaterial.js";
-import { ExtendEventDispatcher } from "../../custom/ExtendEventDispatcher.js";
-
-var texLoader = new THREE.TextureLoader()
-
-const labelProp = {
-    sizeInfo: {minSize : 200 ,  maxSize : 250,   nearBound : 0.8, farBound : 10},
-    backgroundColor:{r: 255, g: 255, b: 255, a: 0.4 },
-    textColor:{r: 0, g: 0, b: 0, a: 1 }, 
-    borderRadius: 15,
-    renderOrder:10
-}
-
-let standardMarkerMat 
-let markerTex
-let getMarerMat = function(){
-    if(!markerTex) {
-        markerTex = {
-            default:texLoader.load( Potree.resourcePath+'/textures/marker.png' ),
-            ring:texLoader.load( Potree.resourcePath+'/textures/marker2.png' )
-        }
-        markerTex.default.anisotropy = 4 // 各向异性过滤 .防止倾斜模糊
-        markerTex.ring.anisotropy = 4  
-        //有可能被点云遮住吗。 
-     
-    }
-    return  new DepthBasicMaterial({opacity:0.7, side: THREE.DoubleSide , map:markerTex.default ,transparent:true, 
-        clipDistance: 2,  occlusionDistance:1,  //不能设置太短,因为过渡时深度不准确
-        //depthTest: !!Potree.settings.useDepthTex,
-        useDepth:  !!Potree.settings.useDepthTex
-        //改为DepthBasicMaterial是因为原Basic的材质过渡时会先隐藏后出现
-    })    
-}
-//显示全景图时marker没有被遮挡,如果需要,要换成depthBasicMaterial  或者直接把skybox的深度修改(拿到深度贴图后更如此)
-let planeGeo = new THREE.PlaneBufferGeometry(0.2,0.2);
-
-
-
-let sg = new THREE.SphereGeometry(0.1, 8, 8);
-let smHovered = new THREE.MeshBasicMaterial({/* side: THREE.BackSide,  */color: 0xff0000});
-
-let sm = new THREE.MeshBasicMaterial({/* side: THREE.BackSide */});
-
-
-
-var rot90 = new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(0,0,1),  Math.PI/2 ); //使用的是刚好适合全景图的,给cube贴图需要转90°
-//var rot90 = new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(1,0,0),  -Math.PI/2 ); //4dkk->navvis
-//var rot901 = new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(0,1,0), -Math.PI/2 ); //整张球幕图要旋转下
-//rot90 = new THREE.Quaternion().multiplyQuaternions(  rot901, rot90)   
-var old = null;
-/* 
-转成四维看看的axis:
-var a = new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(0,0,1), THREE.Math.degToRad(-90))  因为四维的要绕y转90
-这里的quaternion.multiply(a);
- 
-先乘再换顺序 w : q.w,  x:q.x , y:-q.z, z:q.y
-
- */
-
-//暂时直接用4dkkconsole输出的数据 
-class Panorama extends ExtendEventDispatcher{
-
-	constructor(o,  images360){//file, time, longitude, latitude, altitude, course, pitch, roll
-        super()
-        this.id = o.id; //唯一标识
-        this.images360 = images360
-        this.visible = true  //for viewer 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.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)
-        })
-        /*  
-        漫游点可见性:旧
-            level       reason                           类型
-            2(最高)buildingChange(不在此楼层)        unvisible   
-            1       modeIsShowPanos(漫游模式)          visible    //不记得为什么加这个了,所以重写
-            0       pointcloudVisi(隐藏了数据集)       unvisible
-         */
-         
-         /* 
-        漫游点可见性:新
-            level       reason                           类型
-            2(最高)buildingChange(不在此楼层)        unvisible   
-            1       ifShowMarker(marker显示开关)       unvisible 
-            0       pointcloudVisi(隐藏了数据集)       unvisible
-         */ 
-         
-        
-        if(Potree.settings.editType == 'pano'){//漫游点拼合编辑
-            this.uuid = o.uuid  //因为有多个数据集 所以会重复
-            this.index = o.index  //下标, 用于visibles
-            this.pointcloud = viewer.scene.pointclouds.find(e=>e.panoUuid == o.uuid) 
-            this.pointcloud.panos.push(this)
-            this.sid = this.pointcloud.dataset_id + '|' + this.uuid  //不会更改的标记  用于entity.panos里的标记
-            
-            
-            this.panosData = o
-            
-            //数据中原本的位置朝向
-            this.dataPosition = new THREE.Vector3().copy(o.pose.translation) 
-            this.dataQuaternion = new THREE.Quaternion().copy(o.pose.rotation) 
-            this.dataRotation = new THREE.Euler().setFromQuaternion(this.dataQuaternion) 
-            
-            
-            //因为位置朝向随着点云位置改变,所以直接运用到点云上,这里清零
-            this.originPosition = new THREE.Vector3()   //{x: 0, y: 0, z: 0}
-            this.quaternion = new THREE.Quaternion()  //{w: 0, x: 0, y: 0, z: 1}
-            //this.quaternion4dkk = math.convertVisionQuaternion(this.quaternion)//4dkk内使用的quaternion 
-            this.visibles = o.visibles 
-            
-            
-            const height = 1.4; //相机高度
-            this.originFloorPosition = this.originPosition.clone()
-            this.originFloorPosition.z -= height
-            
-            
-            /* this.originPosition = new THREE.Vector3().copy(o.pose.translation)  //{x: 0, y: 0, z: 0}
-            this.quaternion = new THREE.Quaternion().copy(o.pose.rotation) //{w: 0, x: 0, y: 0, z: 1}
-            //this.quaternion4dkk = math.convertVisionQuaternion(this.quaternion)//4dkk内使用的quaternion 
-            this.visibles = o.visibles 
-            this.pointcloud = viewer.scene.pointclouds.find(e=>e.dataset_id == o.uuid) 
-            this.pointcloud.panos.push(this)
-            
-            const height = 1.5; //相机高度
-            this.originFloorPosition = this.originPosition.clone()
-            this.originFloorPosition.z -= height
-             */
-            
-            
-        }else{
-            this.originPosition = new THREE.Vector3().fromArray(o.dataset_location) 
-            this.originFloorPosition = new THREE.Vector3().fromArray(o.dataset_floor_location)
-            
-            this.originID = parseInt(o.file_id)//"file_id":"00022"对应是原本的4dkk的id --来自vision.txt
-             
-            this.pointcloud = viewer.scene.pointclouds.find(e=>e.dataset_id == o.dataset_id) || viewer.scene.pointclouds[0]
-            this.pointcloud.panos.push(this)
-            
-            //this.sid = this.pointcloud.sceneCode + '|' + this.originID  //不会更改的标记
-            this.sid = this.pointcloud.dataset_id + '|' + this.originID  //不会更改的标记
-            //全景图和Cube的水平采样起始坐标相差90度 
-            
-
-            /* if(from4dkk){
-                var qua = o.dataset_orientation 
-                
-                var quaternion = new THREE.Quaternion().fromArray(qua)
-                    quaternion = new THREE.Quaternion().multiplyQuaternions(quaternion,  rot901);//整张球幕图要旋转下  因为在4dkk里转过,还原。如果是tiles的不用
-                this.quaternion = new THREE.Quaternion(quaternion.x, -quaternion.z, quaternion.y, quaternion.w) //转化坐标
-                    
-            }else{ */
-            
-                
-                var qua = o.dataset_orientation 
-                qua = [qua[1], qua[2], qua[3], qua[0]] 
-                this.quaternion = new THREE.Quaternion().fromArray(qua)
-                this.quaternion4dkk = math.convertVisionQuaternion(this.quaternion)//4dkk内使用的quaternion 
-                this.quaternion2 = this.quaternion.clone()
-                this.quaternion = new THREE.Quaternion().multiplyQuaternions(this.quaternion,  rot90);//全景图和Cube的水平采样起始坐标相差90度,cubeTex转90度
-                
-                this.rotation4dkk = new THREE.Euler().setFromQuaternion(this.quaternion4dkk)
-                
-             //}
-             
-             
-                //this.quaternion1 = Potree.Utils.QuaternionFactory.fromArray(o.dataset_orientation)
-                //同quaternion
-
-          
-            //let xy = this.transform.forward([this.longitude, this.latitude]);  
-            this.file = `https://4dkk.4dage.com/images/images${Potree.settings.number}/pan/high/${this.id}.jpg`
-            
-             
-            
-        }
-        this.rotation = new THREE.Euler().setFromQuaternion(this.quaternion) 
-        this.build()
-        this.transformByPointcloud() //初始化位移
-        
-        {//tile
-            this.minimumTiledPanoLoaded = !1;
-            this.highestPartialTileRenderOpCompleted = 0;
-            this.highestFullTileRenderOpCompleted = 0;
-            this.shouldRedrawOnBaseLoaded = !1;
-            this.resolutionPromise = {}
-            this.tiledPanoRenderTarget = null;
-            this.zoomed = !1;
-            
-            
-            
-           
-            images360.panoRenderer.addEventListener(PanoRendererEvents.TileRenderSuccess, this.onTileRendered.bind(this));
-            images360.panoRenderer.addEventListener(PanoRendererEvents.PanoRenderComplete, this.onPanoRendered.bind(this));
-            images360.panoRenderer.addEventListener(PanoRendererEvents.TileRenderFailure, this.onTileRenderFail.bind(this));
-            images360.panoRenderer.addEventListener(PanoRendererEvents.UploadAttemptedForAllTiles, this.onUploadAttemptedForAllTiles.bind(this));
-            
-        }
-        
-        
-        
-        this.addEventListener('hoverOn', (e)=>{//from Map
-            if(!e.byMainView){ 
-                this.hoverOn(e) 
-            } 
-        })
-        
-        this.addEventListener('hoverOff', (e)=>{
-            if(!e.byMainView){
-                this.hoverOff(e) 
-            } 
-        })
-	}
-    
-
-
-    setEnable(enable){//是否可以走
-        viewer.updateVisible(this, 'isEnabled', enable) //令所有marker不可见
-
-        this.enabled = enable 
-        //如果当前在全景模式且在这个点,需要切换显示吗? 目前用不到 
-    }
-
- 
-    loadDepthImg(){ 
-        if(!this.pointcloud.hasDepthTex || this.depthTex || this.depthTexLoading)return
-        this.depthTexLoading = true
-        let src = Potree.settings.number == 'SS-t-7DUfWAUZ3V' ?  `${Potree.scriptPath}/data/${Potree.settings.number}/depthMap/${this.originID}.png`
-                : `https://laser-oss.4dkankan.com/${Potree.settings.webSite}/${this.pointcloud.sceneCode}/data/${this.pointcloud.sceneCode}/depthmap/${this.originID}.png`
-        let texture = texLoader.load( src, ()=>{
-            this.depthTex = texture
-            this.images360.dispatchEvent({type:'loadedDepthImg', pano:this, loaded:true})
-            this.depthTexLoading = false
-        },(e)=>{//error
-            console.error('loadDepthImg失败, 数据集sceneCode'+ this.pointcloud.sceneCode,  this.id )
-            this.pointcloud.hasDepthTex = false
-            this.images360.dispatchEvent({type:'loadedDepthImg', pano:this, })
-        });
-        texture.wrapS = THREE.RepeatWrapping;
-        texture.flipY = false 
-        texture.magFilter = THREE.LinearFilter
-        texture.minFilter = THREE.LinearFilter
-	}
- 
-    
-    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)
-        */
-        
-        { // orientation
-            //var {course, pitch, roll} = this;
-            //mesh.quaternion.copy(this.quaternion) 
-             
-            //add 
-            //var quaternion = new THREE.Quaternion().multiplyQuaternions(this.quaternion,  rot901);//改  为球目全
-            //quaternion.premultiply(rot90)
-            this.panoMatrix = new THREE.Matrix4().makeRotationFromQuaternion(this.quaternion) 
-            this.oriPanoMatrix = this.panoMatrix.clone()
-            
-            if(this.quaternion2)this.oriPanoMatrix2 = new THREE.Matrix4().makeRotationFromQuaternion(this.quaternion2) 
-        
-            
-            //console.log(this.quaternion)
-            //this.quaternion = quaternion
-        } 
-        
-        
-         
-        let marker = new THREE.Mesh(planeGeo, getMarerMat() ) 
-            marker.name = 'marker_'+this.id
-            marker.up.set(0,0,1)
-            marker.lookAt(marker.up) 
-            marker.scale.set(2,2,2) 
-        this.addEventListener('changeMarkerTex',(e)=>{
-            marker.material.map = markerTex[e.name]  
-        })    
-             
-        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)); 
-    }
-    
-    
-    
-    
-    transformByPointcloud(){
-        
-        let position = this.originPosition.clone().applyMatrix4(this.pointcloud.transformMatrix);//也可以用datasetPosTransform算
-        let floorPosition = this.originFloorPosition.clone().applyMatrix4(this.pointcloud.transformMatrix);
-        this.setPosition(position, floorPosition) 
-        this.panoMatrix = new THREE.Matrix4().multiplyMatrices(this.pointcloud.rotateMatrix, this.oriPanoMatrix  ) 
-        //this.panoMatrix2 =  Potree.Utils.datasetRotTransform({fromDataset:true, pointcloud:this.pointcloud,  matrix:this.oriPanoMatrix, getMatrix:true}) //和上一行结果一样
-        //quaternion也变下
-        if(this.oriPanoMatrix2){ 
-            this.panoMatrix2 = new THREE.Matrix4().multiplyMatrices(this.pointcloud.rotateMatrix, this.oriPanoMatrix2  )//供DepthImageSampler使用 
-            this.panoMatrix2Inverse = this.panoMatrix2.clone().invert(); 
-        }        
-        this.dispatchEvent('rePos')
-    }
-    
-    setPosition(position, floorPosition){
-        this.position = position
-        this.floorPosition = floorPosition
-        //this.mesh.position.copy(this.position)
-        this.marker.position.copy(this.floorPosition) 
-        this.marker.position.z+=0.04//会被点云遮住
-        if(this.label){ 
-            if(Potree.settings.editType == 'pano'){
-                this.label.position.copy(this.position)
-            }else{
-                this.label.position.copy(this.floorPosition)
-            } 
-            this.label.position.z+=0.14
-            this.label.update()
-        }
-        
-        if(this.label2){
-            if(Potree.settings.editType == 'pano'){
-                this.label2.position.copy(this.position)
-            }else{
-                this.label2.position.copy(this.floorPosition)
-            }
-            this.label2.position.copy(this.marker.position)
-            this.label2.update()
-        }
-          
-    }
-    
-    
-    
-    
-    
-    
-    
-    
-    hoverOn(e={}) { 
-        //console.log("hoverOn  " + this.id  )
-        transitions.start(lerp.property(this.marker.material, "opacity", 1), 250)  
-		if(!e.byMap) this.dispatchEvent({type:'hoverOn', byMainView:true})
-        if(!e.byImages360) this.images360.dispatchEvent({type:'markerHover', hovered:true, pano:this})
-    }
-
- 
-
-
-    hoverOff(e={}){
-        //console.log("hoverOff  " + this.id  )
-        transitions.start(lerp.property(this.marker.material, "opacity", 0.5), 250) 
-        if(!e.byMap) this.dispatchEvent({type:'hoverOff',  byMainView:true})
-        if(!e.byImages360) this.images360.dispatchEvent({type:'markerHover', hovered:false, pano:this})
-    }
-    
-    
-    
-    setZoomed(zoomed){
-        this.zoomed = zoomed;
-        Potree.settings.displayMode == 'showPanos' && this.updateSkyboxForZoomLevel(); //放大后换成zoomTarget贴图
-        viewer.dispatchEvent({type:'panoSetZoom', zoomed})
-        
-    }
-    
-    
-    enter(){ 
-        this.setZoomed(!1),
-        viewer.dispatchEvent({type:PanoramaEvents.Enter,  oldPano:old, newPano:this  }  )
-        old = this 
-        //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;
-        } */
-        
-        //console.log("exit pano "+ this.id)
-        
-        viewer.dispatchEvent({type:PanoramaEvents.Exit, pano:this}); 
-    }
-    
-    
-    updateSkyboxForZoomLevel(){
-        if(this.minimumTiledPanoLoaded){
-            this.images360.updateProjectedPanos();
-        }
-         
-    }
-    
-    getSkyboxTexture(){
-     
-        if(this.minimumTiledPanoLoaded)
-        {
-            if(this.zoomed && this.images360.qualityManager.maxRenderTargetSize > this.images360.qualityManager.maxNavPanoSize)//change 如果放大后和不放大都是2k就不用这个
-            {
-                return this.images360.panoRenderer.zoomRenderTarget.texture;   
-            }
-            else
-            {
-                
-                this.tiledPanoRenderTarget.texture.mapping = THREE.UVMapping//add
-                return this.tiledPanoRenderTarget.texture;
-            }
-        }
-        else
-        {
-            return null;
-        }
-         
-    }
-    
-   
-    
-    isLoaded(e){ 
-        if (e && "string" == typeof e)
-            console.error("Wrong panoSize given to Panorama.isLoaded(); a tiled pano uses PanoSizeClass"); 
-        return !!this.minimumTiledPanoLoaded && (!e || this.highestFullTileRenderOpCompleted >= e)//改:原本是:this.highestPartialTileRenderOpCompleted >= e, 希望这代表全部加载完
-     
-    }
-
-    getWaitDeferred(size){//获取不同size的tile贴图的promiss 
-        var t = this.resolutionPromise[this.id];
-        t || (t = {}, this.resolutionPromise[this.id] = t);
-        var i = t[size];
-        return i || (i = {
-            deferred: $.Deferred(),
-            active: !1
-        },
-        t[size] = i),
-        i
-    }
-    
-    clearWaitDeferreds(){
-        var e = this.resolutionPromise[this.id];
-        e || (e = {},
-        this.resolutionPromise[this.id] = e);
-        for (var t in e)
-            if (e.hasOwnProperty(t)) {
-                var i = e[t];
-                i.active = !1,
-                i.deferred = $.Deferred()
-            }
-    }
-    resetWaitDeferred(e){
-        var t = this.getWaitDeferred(e);
-        t.active = !1;
-        t.deferred = $.Deferred();
-    }
-    onTileRendered(ev){  
-        ev.id === this.id && this.dispatchEvent({
-            type:PanoramaEvents.TileLoaded, 
-            size:ev.panoSize, index:ev.tileIndex, count:ev.totalTiles
-        });
-    }
-
-    onPanoRendered(ev) { 
-        if(ev.id === this.id)  
-        {
-            this.minimumTiledPanoLoaded = !0;
-            this.updateSkyboxForZoomLevel();//更新贴图 setProjected
-            ev.panoSize > this.highestPartialTileRenderOpCompleted && (this.highestPartialTileRenderOpCompleted = ev.panoSize);//应该是更新最高获取到的Partial size
-            ev.updateFullComplete && ev.panoSize > this.highestFullTileRenderOpCompleted && (this.highestFullTileRenderOpCompleted = ev.panoSize); //应该是更新最高获取到的Full size
-            //this.dispatchEvent("load", ev.panoSize);
-            viewer.ifAllLoaded( this);
-            this.dispatchEvent({type:PanoramaEvents.LoadComplete, size:ev.panoSize, count:ev.totalTiles});
-        }
-    }
- 
-    onTileRenderFail(ev) { 
-        ev.id === this.id && this.dispatchEvent({type:PanoramaEvents.LoadFailed   });
-    }
-    onUploadAttemptedForAllTiles(ev) { 
-        if (ev.id === this.id) {        
-            var n = this.images360.qualityManager.getPanoSize(PanoSizeClass.BASE);
-            if(ev.panoSize === n && this.shouldRedrawOnBaseLoaded) //shouldRedrawOnBaseLoaded一直是false。在4dkk里只有初始点在quickstart后变为true。
-            {
-                this.shouldRedrawOnBaseLoaded = !1;
-                this.panoRenderer.resetRenderStatus(this.id, !0, !1);
-                this.panoRenderer.renderPanoTiles(this.id, null, !0, !0);
-            }
-        }
-    }
-
-    
-    
-    createTextLabel(){
-        this.removeTextLabel()
-        this.label = new TextSprite(Object.assign({},
-           labelProp, {text: this.id }) //{text: `id:${this.id}, dataset:${this.pointcloud.name}, 4dkkId:${this.originID}`}
-        ); 
-        this.images360.node.add(this.label);
-        this.floorPosition && this.label.position.copy(this.floorPosition)
-    }
-    
-    createTextLabel2(){ 
-        let labelProp2 = {
-            //sizeInfo: {minSize : 200 ,  maxSize : 250,   nearBound : 0.8, farBound : 10},
-            backgroundColor:{r: 255, g: 255, b: 255, a: 0 },
-            textColor:{r:255 , g: 255, b: 255, a: 1 }, 
-            textBorderColor:{r:30 , g:30, b: 30, a: 1 }, 
-            textBorderThick:3,
-            dontFixOrient:true,
-            renderOrder:10,
-            fontsize:30,
-        } 
-        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}`}
-        ); 
-        this.images360.node.add(this.label2);
-        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)
-    }
-    
-    removeTextLabel(){
-        if(this.label){ 
-            this.label.parent.remove(this.label);
-        }
-    }
-    
-    dispose(){
-        
-        let i = viewer.images360.panos.indexOf(this);
-        if(i==-1)return
-        
-        this.marker.parent.remove(this.marker)
-        
-        
-        this.removeTextLabel()
-        if(this.depthTex) this.depthTex.dispose()
-        viewer.images360.panos.splice(i,1);
-        
-        this.dispatchEvent('dispose')
-        //删除tile贴图、depthTex等以后再写
-    }
-    
-};
-
-
- 
-
-Panorama.prototype.loadTiledPano = function() {
-    //var downloads = []  , t = [];
-    var downloaded = {}  , eventAdded = {}, latestPartialRequest = {}; //每个pano对应一组这些
-         
-    return function(size, dirs, fov, o, a, download) {
-        var dir = dirs.datasetsLocal.find(e=>e.datasetId == this.pointcloud.dataset_id).direction;
-        //var dir = dirs
-         
-        
-        null !== o && void 0 !== o || (o = !0),
-        null !== a && void 0 !== a || (a = !0);
-        var l = this.getWaitDeferred(size)
-          , c = l.deferred
-          , h = null
-          , u = null; 
-        fov && ("number" == typeof fov ? h = fov : (h = fov.hFov, u = fov.vFov))  
-        
-        if (!this.isLoaded(size)) {
-            //console.log('loadTiledPano', this.id, size, fov)
-            if (!l.active) {
-                l.active = !0 
-                let name = this.id + ":" + size
-                downloaded[name] = downloaded[name] || []
-                /* 
-                this.downloaded = downloaded
-                this.latestPartialRequest = latestPartialRequest 
-                 */
-                latestPartialRequest[name] = null
-                     
-                if (fov) {
-                    let tileArr = []//add 
-                    var d = TileUtils.matchingTilesInDirection(this, size, dir, h, u, tileArr);
-                    
-                    latestPartialRequest[name] = tileArr
-                    downloaded[name].forEach((e)=>{
-                         let item = latestPartialRequest[name].find(a=>e.faceTileIndex == a.faceTileIndex && e.face == a.face)  
-                         if(item){
-                             item.loaded = true
-                         }
-                    })
-                    if(!latestPartialRequest[name].some(e=>!e.loaded)){//所需要的全部加载成功
-                        //let total = TileUtils.getTileCountForSize(size)
-                        //this.onPanoRendered(this.id, size, total, !0);
-                        c.resolve(size/* , total */);
-                        this.resetWaitDeferred(size)
-                        //console.log('该部分早已经加载好了'+size, this.id)
-                        latestPartialRequest[name] = null
-                    }
-                     
-                    //console.log("Loading partial pano: " + this.id + " with " + d + " tiles")
-                }
-                if(!eventAdded[this.id]) {
-                    eventAdded[this.id] = !0 
-                    
-                    this.addEventListener(PanoramaEvents.LoadComplete, function(ev/* e, t */) {//本次任务全部加载完毕 
-                        
-                        //console.warn('点位(可能部分)下载完成 ', 'id:'+this.id,  'size:'+ev.size ) 
-                        
-                        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) {
-                        var t = this.getWaitDeferred(e).deferred;
-                        t && "pending" === t.state() && this.highestPartialTileRenderOpCompleted >= ev.t && (t.reject(ev.t),
-                        this.resetWaitDeferred(ev.t))//恢复active为false
-                    }.bind(this)) 
-                    
-                    this.addEventListener(PanoramaEvents.TileLoaded, function(ev/* t, i, n */) {//每张加载完时
-                        
-                        //console.log('tileLoaded', 'id:'+this.id,  'size:'+ev.size, 'tileIndex:'+ev.index )
-                        let tileIndex = ev.index
-                        let total = ev.count
-                        let size = ev.size
-                        let name = this.id + ":" + size 
-                        downloaded[name] = downloaded[name] || [] //不是所有的加载都是从loadTiledPano获取的所以会有未定义的情况
-                        
-                        let {faceTileIndex,face} = TileUtils.getTileLocation(size, tileIndex, {}) 
-                        downloaded[name].push({faceTileIndex,face})    
-                        var r = this.getWaitDeferred(size).deferred;
-                        if (r && "pending" === r.state()) { 
-                            r.notify(size, tileIndex, total);
-                            if(latestPartialRequest[name]){
-                                let item = latestPartialRequest[name].find(e=>e.faceTileIndex == faceTileIndex && e.face == face)    
-                                item && (item.loaded = true ) 
-                                
-                                if(!latestPartialRequest[name].some(e=>!e.loaded)){//所需要的局部tiles全部加载成功
-                                    this.onPanoRendered(this.id, size, total, !0); //onPanoRendered还会触发 PanoramaEvents.LoadComplete   
-                                    r.resolve(size, total);
-                                    this.resetWaitDeferred(size)
-                                    //console.log('该部分加载好了'+size, this.id)
-                                    latestPartialRequest[name] = null
-                                }
-                                
-                            } 
-                        } 
-
-
-    
-                        
-                        /* var r = this.getWaitDeferred(ev.size).deferred;
-                        if (r && "pending" === r.state()) {
-                            r.notify(ev.size, ev.index, ev.count);
-                             
-                            var o = downloads[this.id + ":" + ev.size];
-                            if(o){//如果有规定下载哪些tile,只需要下载这些tile则LoadComplete
-                                o.tileCount++ 
-                                
-                                if(o.tileCount === o.targetTileCount){//达到下载目标数
-                                    this.onPanoRendered(this.id, ev.size, ev.count, !0);
-                                    r.resolve(ev.size, ev.count);
-                                    this.resetWaitDeferred(ev.size)
-                                }
-                            }
-                        } */
-                    }.bind(this))
-                }
-            }
-            this.images360.tileDownloader.clearForceQueue(),
-            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)
-        }
-        return c.promise()
-    }
-}()
-
-
-/* 
-
-    经观察发现,navvis的也存在的问题是点云和全景有微小的偏差,导致远处的热点在全景和点云上看位置差别感大,比如一个在路上一个在天空上。
-
-
- */
-export default Panorama

File diff suppressed because it is too large
+ 0 - 1198
src/modules/Images360/tile/PanoRenderer.js


+ 0 - 171
src/modules/Images360/tile/QualityManager.js

@@ -1,171 +0,0 @@
-
-import * as THREE from "../../../../libs/three.js/build/three.module.js";
- 
-import browser from '../../../utils/browser.js' 
-import {settings,config} from '../../../settings.js'
-import {ModelManagerEvents,PanoSizeClass} from '../../../defines.js'
-
-
-
-export default class QualityManager {
-    constructor(e, t, i) {
-      
-        this.maxNavPanoSize = -1;
-        this.maxZoomPanoSize = -1;
-        this.devicePixelDensity = e;
-        this.deviceScreenSize = t;
-        this.clientBandwidth = i;
-        this.panoSizeClassMap = {};
-        this.useHighResolutionPanos = !0;  //是否能够使用2k及以上图
-        this.useUltraHighResolutionPanos = !1;
-        this.modelHasUltraHighPanos = !1;
-        this.qualityManager = this;
-        
-        this.maxRenderTargetSize = browser.isMobile() ? 2048 : 4096  //add
-        this.init()
-    }
-
-    init(e ) {
-        //var metadata = store.getters['scene/metadata'] ;//有时候请求不到
-        //if(metadata.sceneSource == 11 || metadata.sceneScheme == 12){
-        /* if(config.tileClass == '1k'){
-            this.useHighResolutionPanos = false    //xzw add 只加载1k
-        } */
-         
-        
-        this.buildPanoSizeClassMap(this.devicePixelDensity, this.deviceScreenSize, this.clientBandwidth);
-        this.ultraHighSize = this.getPanoSize(PanoSizeClass.ULTRAHIGH);
-        this.highSize = this.getPanoSize(PanoSizeClass.HIGH);
-        this.standardSize = this.getPanoSize(PanoSizeClass.STANDARD);
-        this.baseSize = this.getPanoSize(PanoSizeClass.BASE);
-        config.tiling.maxZoomPanoQuality && this.ultraHighSize <= config.tiling.maxZoomPanoQuality && (config.tiling.allowUltraHighResolution = !0);
-        this.highQualityThreshold = browser.valueFromHash("threshold2k", config.windowHeightHighQualityThreshold);
-        this.updateMaximums();
-        //e.on(ModelManagerEvents.ActiveModelChanged, this.onModelChanged.bind(this));
-    }
-
-    updateFromModel(e) {
-        //this.updateHighResolutionSettings(e) 
-        this.updateUltraHighResolutionSettings(e)
-    }
-
-    /* updateHighResolutionSettings(e) {
-        this.useHighResolutionPanos = !0 
-        this.updateMaximums()
-    } */
-
-    updateUltraHighResolutionSettings(e) {
-        if (config.tiling.allowUltraHighResolution && this.modelHasUltraHighPanos) {
-            this.useUltraHighResolutionPanos = !0;
-        } else {
-            this.useUltraHighResolutionPanos = !1;
-        }
-        this.updateMaximums();
-    }
-
-    enableUltraHighQualityMode() {
-        this.modelHasUltraHighPanos = !0;
-        this.updateUltraHighResolutionSettings(null);
-    }
-
-    ultraHighQualityModeEnabled() {
-        return this.modelHasUltraHighPanos
-    }
-
-    onModelChanged(e) {
-        this.updateFromModel(e.model),
-            this.updateMaximums()
-    }
-
-    updateMaximums() {
-        this.maxNavPanoSize = config.tiling.maxNavPanoQuality || this.detectMaxNavPanoSize(),
-        this.maxZoomPanoSize = config.tiling.maxZoomPanoQuality || this.detectMaxZoomPanoSize(),
-        this.maxZoomPanoSize < this.maxNavPanoSize && (this.maxNavPanoSize = this.maxZoomPanoSize)
-    }
-
-    buildPanoSizeClassMap() {
-        this.panoSizeClassMap[PanoSizeClass.BASE] = 512,
-            this.panoSizeClassMap[PanoSizeClass.STANDARD] = 1024,
-            this.panoSizeClassMap[PanoSizeClass.HIGH] = 2048,
-            this.panoSizeClassMap[PanoSizeClass.ULTRAHIGH] = 4096
-    }
-
-    getPanoSize(e) {
-        return this.panoSizeClassMap[e]
-    }
-
-    getMaxPossiblePanoSize() {
-        return this.getPanoSize(PanoSizeClass.ULTRAHIGH)
-    }
-
-    getMaxPanoSize() {
-        return this.maxZoomPanoSize
-    }
-
-    getMaxNavPanoSize() {
-        return this.maxNavPanoSize
-    }
-
-    getMaxZoomPanoSize() {
-        return this.maxZoomPanoSize
-    }
-
-    detectMaxNavPanoSizeClass() {
-        //return this.useHighResolutionPanos ? browser.isMobile() ? PanoSizeClass.STANDARD : window.innerHeight < this.highQualityThreshold ? PanoSizeClass.STANDARD : PanoSizeClass.HIGH : PanoSizeClass.STANDARD
-       /*  if(config.name == 'decor'){
-            return PanoSizeClass.STANDARD
-        }
-        return PanoSizeClass.HIGH  */
-        switch(Potree.settings.navTileClass){  
-            case '1k':
-                return PanoSizeClass.STANDARD;
-                break;
-            case '2k':             
-            default:
-                return PanoSizeClass.HIGH;
-        }
-        
-        
-    }
-
-    detectMaxNavPanoSize() {
-        var e = this.detectMaxNavPanoSizeClass();
-        return this.getPanoSize(e)
-    }
-
-    detectMaxZoomPanoSize() { 
-        if(this.zoomLevelResolution){
-            if(this.zoomLevelResolution == '4k' && this.useUltraHighResolutionPanos){
-                return this.getPanoSize(PanoSizeClass.ULTRAHIGH);
-            }else if(this.zoomLevelResolution == '1k' || !this.useHighResolutionPanos){
-                return this.getPanoSize(PanoSizeClass.STANDARD);
-            }else{
-                return this.getPanoSize(PanoSizeClass.HIGH);
-            }
-        }else{
-            if (this.useHighResolutionPanos) {
-                /* if (browser.isMobile()) {//手机版如果要2k的将这里去掉
-                    if (settings.tiling.mobileHighQualityOverride) {
-                        return this.getPanoSize(PanoSizeClass.HIGH);
-                    } else {
-                        return this.getPanoSize(PanoSizeClass.STANDARD);
-                    }
-                } else  */if (this.useUltraHighResolutionPanos ) {
-                    return this.getPanoSize(PanoSizeClass.ULTRAHIGH);
-                } else {
-                    return this.getPanoSize(PanoSizeClass.HIGH);
-                }
-            } else {
-                return this.getPanoSize(PanoSizeClass.STANDARD);
-            }
-            
-            
-        }
-        
-    }
-    
-    
-    
-    
-    
-}

+ 0 - 513
src/modules/Images360/tile/TileDownloader.js

@@ -1,513 +0,0 @@
-import {TileDownloaderEvents, DownloadStatus} from '../../../defines.js'
-import * as THREE from "../../../../libs/three.js/build/three.module.js";
- 
-import TilePrioritizer from './TilePrioritizer.js'
-import TileUtils from './TileUtils.js'
-import {ExtendEventDispatcher} from "../../../custom/ExtendEventDispatcher.js";
- 
-import {settings, config} from '../../../settings.js' 
-import {
-    http
-} from '../../../utils/request.js' 
-
-
-
-window.downloaded = {}
-window.startdownloads = [];
-
-
-
-
-class TileDownloader extends ExtendEventDispatcher{
-    constructor( ) {
-        super()
-        this.panos = null;
-        this.retryMinimumTime = 1e4;
-        this.panoLoadCallbacks = {};
-        this.downloadDescriptors = {};
-        this.priorityQueue = [];
-        this.forceQueue = [];
-        this.activeDownloads = [];
-        this.tilePrioritizer = null;
-        this.refreshInterval = null;
-        this.processPriorityQueue = !1;
-        this.concurrentDownloads = 6;//e.concurrentDownloads || 1;
-        this.downloadTestResults = {};
-
-        this.freeze = Object.freeze({
-            Testing: 1,
-            Success: 2,
-            Fail: 3
-        });
-        
-        this.visible = true //add   借用viewer.updateVisible来判断是否start
-         
-        viewer.addEventListener('pageVisible', (e)=>{//不可见时不refreshUpdateInterval 
-            //console.log('visibilitychange:', state)
-            viewer.updateVisible(this,  'pageVisible', e.v) 
-            this.judgeStart() 
-        }) 
-         
-    }
-
-    setPanoData(e, t /* , i */) {
-        this.panos = e,
-        this.imagePanos = t 
-          //  this.panoGroupId = i
-    }
-  
-    start() { 
-        this.downloadCubeTex = true 
-        if(!Potree.settings.useDepthTex){
-            viewer.updateVisible(this,'pano', true )
-            this.judgeStart()            
-        }else{
-            this.refreshInterval || this.judgeStart()
-        }
-    }
-
-    stop() {
-        this.downloadCubeTex = false
-        if(!Potree.settings.useDepthTex){
-            viewer.updateVisible(this,'pano', false )
-            this.judgeStart()
-        } 
-    }
-
-    judgeStart(){//add
-        if(this.visible){
-            //console.log('judgeStart true')
-            this.started = true 
-            this.refreshUpdateInterval(0)
-        }else{
-            //console.log('judgeStart false')
-            this.started = false
-            window.clearTimeout(this.refreshInterval)
-        }
-        
-    }
-
-    refreshUpdateInterval(e) {
-        e || (e = 0),
-            this.refreshInterval = window.setTimeout(function() {
-                    var e = this.update();
-                    e ? this.refreshUpdateInterval(TileDownloader.ACTIVE_REFRESH_DELAY) : this.refreshUpdateInterval(TileDownloader.IDLE_REFRESH_DELAY)
-                }
-                .bind(this), e)
-    }
-
-    update() { 
-        if(this.downloadCubeTex){ //可以下载贴图
-            var e = this.forceQueue.length > 0;
-            this.processQueueForDownloading(this.forceQueue);
-            if (this.processPriorityQueue) {
-                this.queuePrioritizedTilesForPanos(this.panos);
-                this.priorityQueue.length > 0 && (e = !0);
-                this.processQueueForDownloading(this.priorityQueue);
-            }
-            return e 
-        }else{//仅下载depthTex
-            this.tilePrioritizer.filterDepthTex(this.panos)
-        }
-        
-    }
-
-    
-
-    queuePrioritizedTilesForPanos(e) {
-        this.tilePrioritizer && (this.clearQueue(this.priorityQueue),
-            this.tilePrioritizer.filterAndPrioritize(this.priorityQueue, e, this),
-            this.clearFromQueue(this.priorityQueue, DownloadStatus.None, !0),  //去除state为DownloadStatus.None的(可能是去除已经在下载的)
-            this.setStatusOrRemoveForAllDescriptors(this.priorityQueue, DownloadStatus.Queued))
-    }
-
-    clearQueue(e) {//停止下载并清空
-        this.setStatusForAllDescriptors(e, DownloadStatus.None),
-            e.length = 0
-    }
-    
-    clearForceQueue() {
-        this.clearQueue(this.forceQueue)
-    }
-    
-    clearFromQueue(e, t, i) {
-        for (var n = 0; n < e.length; n++) {
-            var r = e[n];
-            r && (t === r.status && !i || t !== r.status && i) && (e[n] = null)
-        }
-    }
-
-    setStatusForAllDescriptors(e, t) {
-        for (var i = 0; i < e.length; i++) {
-            var n = e[i];
-            n && (n.status = t)
-        }
-    }
-
-    setStatusOrRemoveForAllDescriptors(e, t) {
-        for (var i = 0; i < e.length; i++) {
-            var n = e[i];
-            n && (n.status !== t ? n.status = t : e[i] = null)
-        }
-    }
-
-    getTileDownloadDescriptors(pano, size) {//获取该pano的该size的全部的tile的descriptor
-        var i = this.getAllTileDownloadDescriptorsForPano(pano),
-            n = i[size];
-        return n || (n = this.buildDownloadDescriptorArray(size),//创建的全部是空的
-                i[size] = n,
-                this.initTileDownloadDescriptors(n, pano, size)),//绑定到该pano size
-            n
-    }
-
-    getAllTileDownloadDescriptorsForPano(pano) {//新建空Descriptors
-        var t = this.downloadDescriptors[pano.id];
-        return t || (t = {},
-                this.downloadDescriptors[pano.id] = t),
-            t
-    }
-
-    processQueueForDownloading(e, t) {//执行下载任务
-        this.cleanupActiveDownloads();
-        if (this.activeDownloads.length < this.concurrentDownloads || t) {
-            var i = t ? e.length : this.concurrentDownloads - this.activeDownloads.length;
-
-            for (var n = 0, r = 0; n < i && e.length > 0; r++) {
-                var o = e.shift();
-                
-                
-                if(o){
-                    //add 为了防止1024的在512前下载完,这里强行等待512下载完毕再开始下载
-                    if(o.panoSize > 512 && !this.isPanoDownloaded(o.pano, 512) ){
-                        //console.log('512的还没下载好呢!')
-                        e.push(o)
-                        break;//一般512的都是连续下载的,所以后面就都不是512了直接中断 
-                    } 
-                    
-                    this.startDownload(o)
-                    n++
-                }
-                
-            }
-        }
-    } 
-    
-    
-    
-    
-    testDownload(panoSize, tileSize, callback) {
-        var n = this.downloadTestResults[panoSize];
-        if (n)
-            return void(n === this.freeze.Success ? callback(!0) : n === this.freeze.Fail && callback(!1));
-        this.downloadTestResults[panoSize] = this.freeze.Testing;
-        var r = this.panos[0],
-            o = this.getTileUrl({pano:r, panoSize, tileSize, tileIndex:0}   /* r.id, panoSize, tileSize, 0 */),
-            a = function(t) {
-                this.downloadTestResults[panoSize] = this.freeze.Success,
-                    callback(!0)
-            }
-            .bind(this),
-            s = function() {
-                this.downloadTestResults[panoSize] = this.freeze.Fail,
-                    callback(!1)
-            }
-            .bind(this);
-        this.loadImage(o, 0, a, s)
-    }
-
-    startDownload(e) {//开始下载啦
-        //console.log('startDownload')
-        
-        startdownloads.push(e)
-        
-        e.status = DownloadStatus.Downloading;
-        var t = this.getTileUrl(e/* e.pano.id, e.panoSize, e.tileSize, e.tileIndex, e.pano.alignmentType */);//xzw add alignmentType
-        if(!t)return;
-        this.activeDownloads.push(e);
-        this.loadImage(t, TileDownloader.DOWNLOAD_RETRIES, this.downloadComplete.bind(this, e), this.downloadFailed.bind(this, e))
-    }
-
-    downloadFailed(e, t) {}
-
-    downloadComplete(e, t) {//下载成功时
-        //if (e.panoGroupId === this.panoGroupId) {
-            var i = this.getPanoLoadCallbacks(e.pano, e.panoSize);
-            e.status = DownloadStatus.Downloaded,
-                i && i.onProgress && i.onProgress(e.pano, e.panoSize);
-            var n = {
-                panoId: e.pano.id,
-                image: t,
-                tileSize: e.tileSize,
-                panoSize: e.panoSize,
-                tileIndex: e.tileIndex,
-                faceTileIndex: e.faceTileIndex,
-                totalTiles: e.totalTiles,
-                face: e.face,
-                tileX: e.tileX,
-                tileY: e.tileY,
-                direction: e.direction
-            };
-            
-            downloaded[e.pano.id] || (downloaded[e.pano.id]={512:[],1024:[],2048:[]})
-            downloaded[e.pano.id][e.panoSize] || (downloaded[e.pano.id][e.panoSize] = [])
-            downloaded[e.pano.id][e.panoSize].push(e)
-            if(e.panoSize != 512 && downloaded[e.pano.id][512].length<6){
-                console.warn('没下完')
-            }
-            
-            
-            
-            e.image = t,
-            this.dispatchEvent({type:TileDownloaderEvents.TileDownloadSuccess, desc:n} ) 
-            this.isPanoDownloaded(e.pano, e.panoSize) && (n = {
-                    panoId: e.pano.id,
-                    tileSize: e.tileSize,
-                    panoSize: e.panoSize
-                },
-                this.dispatchEvent({type:TileDownloaderEvents.PanoDownloadComplete, desc:n}),
-                i && i.onLoad && i.onLoad(e.pano, e.panoSize))
-        //}
-    }
-
-
-    isPanoDownloaded(e, t) {
-        var i = this.getTileDownloadDescriptors(e, t);
-        if (i.length <= 0)
-            return !1;
-        for (var n = 0; n < i.length; n++) {
-            var r = i[n];
-            if (r.status !== DownloadStatus.Downloaded)
-                return !1
-        }
-        return !0
-    }
-
-    setPanoLoadCallbacks(e, t, i, n, r) {
-        var o = e.id + ":" + this.qualityManager.getPanoSize(t);
-        this.panoLoadCallbacks[o] = {
-            onLoad: i,
-            onFail: n,
-            onProgress: r
-        }
-    }
-
-    getPanoLoadCallbacks(e, t) {
-        var i = e.id + ":" + t;
-        return this.panoLoadCallbacks[i]
-    }
-
-    buildDownloadDescriptorArray(e) {
-        for (var t = TileUtils.getTileCountForSize(e), i = [], n = 0; n < t; n++) {
-            var r = this.buildDownloadDescriptor();
-            i.push(r)
-        }
-        return i
-    }
-
-    buildDownloadDescriptor() {//Descriptor!
-        var e = {
-            panoGroupId: null,
-            pano: null,
-            panoSize: -1,
-            tileSize: -1,
-            tileIndex: -1,
-            totalTiles: -1,
-            faceTileIndex: -1,
-            status: DownloadStatus.None,
-            url: null,
-            image: null,
-            direction: new THREE.Vector3, //该tile在cube中的方向
-            face: -1,
-            cubeFace: -1,
-            tileX: -1,
-            tileY: -1
-        };
-        return e
-    }
-
-    initTileDownloadDescriptors(e, t, i) {
-        for (var n = 0; n < e.length; n++) {
-            var r = e[n];
-            this.initTileDownloadDescriptor(r, t, i, n)
-        }
-    }
-
-    initTileDownloadDescriptor(desc, pano, size, index) {
-        var r = size >= TileUtils.TILE_SIZE ? TileUtils.TILE_SIZE : size;
-        desc.face = TileUtils.getFaceForTile(size, index);//根据顺序得到的face的index
-        desc.cubeFace = TileUtils.mapFaceToCubemapFace(desc.face);//为了贴图而转化的face index
-        //desc.panoGroupId = this.panoGroupId;//就是场景号
-        desc.pano = pano;
-        desc.panoSize = size;
-        desc.tileSize = r;      //瓦片图size 512
-        desc.tileIndex = index;
-        desc.totalTiles = TileUtils.getTileCountForSize(size);
-        desc.status = DownloadStatus.None;
-        desc.image = null;
-        TileUtils.getTileLocation(desc.panoSize, desc.tileIndex, desc);//得到该tile在这个face中的具体位置(tileX等)
-        TileUtils.getTileVector(desc.panoSize, desc.tileSize, desc.cubeFace, desc.tileX, desc.tileY, TileUtils.LocationOnTile.Center, 0, desc.direction);
-    }
-
-    
-
-    getTiles(d, sceneNum){
-        if(Potree.settings.isLocal2){//新的地址  scene_view_data/场景码/images/tiles
-            return `${Potree.settings.urls.prefix3}/scene_view_data/${sceneNum}/images/${d}`    
-        }
-        
-        return `${Potree.settings.urls.prefix3}/images/images${sceneNum}/${d}`    
-    }
-
-    loadImage(e, t, i, n) {
-        //自己修改了ajax,把getImage改成了loadImg
-        http.loadImage(e, t).then(function(e) {
-            i(e)
-        }).fail(n)
-    }
-}
-TileDownloader.prototype.forceQueueTilesForPano = function() {//根据条件开始加载tile
-    var e = [],
-        t = [];
-    return function(pano, size, dir, hFov, vFov, download) { 
-        e.length = 0;
-        for (var u = this.getTileDownloadDescriptors(pano, size), d = 0; d < u.length; d++) {
-            var p = u[d];
-            p.status !== DownloadStatus.None && p.status !== DownloadStatus.Queued || e.push(p)
-        }
-        if (dir && e.length > 0) {
-            TilePrioritizer.sortPanoTiles(e, pano, dir) //按最佳方向排序e
-            t.length = 0 
-            TileUtils.matchingTilesInDirection(pano, size, dir, hFov, vFov, t);//得到在符合视野标准的集合t
-            
-            
-            
-            for (var f = 0, g = function(e) {
-                return e.face === m.face && e.faceTileIndex === m.faceTileIndex
-            }; f < e.length;) {  //过滤掉不符合角度要求的
-                var m = e[f],
-                    v = t.findIndex(g);
-                v < 0 ? e.splice(f, 1) : f++
-            }
-        }
-        for (var A = 0; A < e.length; A++){
-            this.forceQueue.push(e[A]);         //装载
-        }
-        /* if(e.length){
-            console.log(e)
-        } */
-        
-        this.setStatusForAllDescriptors(this.forceQueue, DownloadStatus.ForceQueued);
-        this.clearFromQueue(this.priorityQueue, DownloadStatus.ForceQueued, !1);
-        download && this.processQueueForDownloading(this.forceQueue, !0);
-    }
-}()
-
-TileDownloader.prototype.cleanupActiveDownloads = function() {
-    var e = [];
-    return function() {
-        e.length = 0;
-        for (var t = 0; t < this.activeDownloads.length; t++) {
-            var i = this.activeDownloads[t];
-            i.status !== DownloadStatus.Downloaded && i.status !== DownloadStatus.Failed && e.push(i)
-        }
-        this.activeDownloads.length = 0,
-        this.activeDownloads.push.apply(this.activeDownloads, e)
-    }
-}()
-
-TileDownloader.prototype.getTileUrl = function() {
-    var e = {
-            256: "256",
-            512: "512",
-            1024: "1k",
-            2048: "2k",
-            4096: "4k"
-        },
-        t = {
-            face: -1,
-            faceTileIndex: -1,
-            tileX: -1,
-            tileY: -1
-        };
-    
-    return function(o={}  ) {  
-        var id = o.pano.originID, ////////
-            panoSize = o.panoSize,
-            tileSize = o.tileSize,
-            tileIndex = o.tileIndex,
-            sceneCode = o.pano.pointcloud.sceneCode
-        var metadata = {sceneScheme:10}  
-        
-        
-        TileUtils.getTileLocation(panoSize, tileIndex, t);
-        var s = Math.floor(panoSize / tileSize),
-            l = s * s,
-            h = Math.floor(tileIndex / l),
-            u = "",
-            d = '',  g = '';
-        
-        
-        
-        if(Potree.settings.isLocal){//原始规则
-            //1 === config.tiling.customCompression && (u = "_" + config.tiling["q" + e[panoSize]]);
-            //1 === o.tiling.customCompression && (u = "_" + o.tiling["q" + e[n]]);
-            d = "tiles/" + id + "/" + e[panoSize] + u + "_face" + h + "_" + t.tileX + "_" + t.tileY + ".jpg" 
-            d =  this.getTiles(d, sceneCode);
-            g = "?"  
-          
-        }else{//阿里云oss的规则   if (metadata.sceneScheme == 10) 
-            
-            d = 'tiles/4k/' + id + '_skybox' + h + '.jpg?x-oss-process=';
-            if (e[panoSize] == '512') {
-                d += 'image/resize,h_512';
-            } else {
-                //4k的图,移动端是1k,pc端是2k,放大才是4k
-                if (e[panoSize] == '1k' || e[panoSize] == '2k') {  //https://4dkk.4dage.com/images/imagesx4iqYDG3/tiles/4k/122_skybox0.jpg?x-oss-process=image/resize,m_lfit,w_1024/crop,w_512,h_512,x_511,y_0
-                    d += 'image/resize,m_lfit,w_' + panoSize + '/crop,w_512,h_512,';
-                } else {
-                    d = 'tiles/4k/' + id + '_skybox' + h + '.jpg?x-oss-process=image/crop,w_512,h_512,';
-                }
-                //起始位置
-                if (t.tileX == 0) {
-                    d += 'x_0,';
-                } else {
-                    d += 'x_' + (512 * t.tileX - 1) + ',';
-                }
-
-                if (t.tileY == 0) {
-                    d += 'y_0';
-                } else {
-                    d += 'y_' + (512 * t.tileY - 1);
-                } 
-            }
-            
-            d = this.getTiles(d, sceneCode);
-            g = "&" 
-        } 
-        
-        d += g + 'time='+o.pano.pointcloud.timeStamp  //加后缀
-         
-        return d;
-    }
-}();
-
-TileDownloader.tilegen = true;
-TileDownloader.IDLE_REFRESH_DELAY = 500;
-TileDownloader.ACTIVE_REFRESH_DELAY = 16;
-TileDownloader.DOWNLOAD_RETRIES = 4;
-
-// var tileconc = TileDownloader.tilegen ? 6 : 2;
-// publicObjectSet.tileDownloader = new TileDownloader({
-//     concurrentDownloads: tileconc
-// });
-
-// export default new  TileDownloader({
-//     concurrentDownloads: TileDownloader.tilegen ? 6 : 2
-// })
-
-
-/* export default new TileDownloader({
-    concurrentDownloads: TileDownloader.tilegen ? 6 : 2
-}) */
-
-export default TileDownloader

+ 0 - 395
src/modules/Images360/tile/TilePrioritizer.js

@@ -1,395 +0,0 @@
- 
-import {DownloadStatus} from '../../../defines.js'
-import {Images360} from '../Images360.js'
-import TileUtils from './TileUtils.js'
-import cameraLight from '../../../utils/cameraLight.js'
-import math from '../../../utils/math.js'
-import Common from '../../../utils/Common.js' 
-import * as THREE from "../../../../libs/three.js/build/three.module.js";
-
-
-
-
-var h = Object.freeze({
-    None: 0,
-    DirectionalFOV: 1
-});
-
-var u = function () {
-    var e = function e(t, i) {
-        var n = e._panoSpaceDir,
-            r = e._fovThreshold,
-            o = e._fovThresholdNarrow,
-            a = Math.max(Math.min(n.dot(t.direction), 1), -1),
-            s = Math.max(Math.min(n.dot(i.direction), 1), -1);
-        return t._dot = a,
-            i._dot = s,
-            a >= r && s < r ? -1 : a < r && s >= r ? 1 : a >= o && s < o ? -1 : a < o && s >= o ? 1 : t.panoSize > i.panoSize ? 1 : i.panoSize > t.panoSize ? -1 : -(a - s)
-    };
-    return e._panoSpaceDir = new THREE.Vector3,
-        e._fovThreshold = -1,
-        e._fovThresholdNarrow = -1,
-        e
-}();
-
-export default class TilePrioritizer {//优先级处理序列
-    constructor(e,t, i, o, a) {
-        this.qualityManager = e;
-        this.maxNavQuality = this.qualityManager.getMaxNavPanoSize();
-        this.maxZoomQuality = this.qualityManager.getMaxZoomPanoSize();
-        this.baseSize = t;
-        this.standardSize = i;
-        this.highSize = o;
-        this.ultraHighSize = a;
-        this.priorityCriteria = new TilePrioritizer.PriorityCriteria(null, new THREE.Vector3(0, 0, 0), new THREE.Vector3(0, 0, -1), new THREE.Vector3(0, 0, -1));
-    }
-
-    updateCriteria(e, t, i, n) {//由player更新
-        this.priorityCriteria.pano = e,
-        this.priorityCriteria.cameraPosition.copy(t),
-        //this.priorityCriteria.cameraDir.copy(i),
-        this.priorityCriteria.cameraDirs = i
-        
-        this.priorityCriteria.upcomingPanos = n,
-        this.maxNavQuality = this.qualityManager.getMaxNavPanoSize(),
-        this.maxZoomQuality = this.qualityManager.getMaxZoomPanoSize()
-          
-            
-    }
-
-    canDownloadSize(e) {
-        return this.maxNavQuality >= e || this.maxZoomQuality >= e && this.zoomingActive
-    }
-
-   
-
-
-
-    /* populateNeighborPanos(e, t, i) {
-        i = i || [],
-            i.length = 0;
-        var n = t.getNeighbours(e);
-        for (var r in n)
-            if (n.hasOwnProperty(r)) {
-                var o = t.get(r);
-                if(!o){
-                    console.log(1)
-                }
-                i.push(o)
-            }
-        return i
-    } */
-
-    populateScoredPanos(e, t, i, dirs, a) {
-        i = i || [],
-            i.length = 0;
-        var s = [Images360.filters.inPanoDirection(e.position, dirs, TilePrioritizer.DIRECTION_SCORE_STRICTNESS), Images360.filters.not(e)],
-            l = [Images360.scoreFunctions.distanceSquared(e), Images360.scoreFunctions.direction(e.position, dirs)],
-            c = Common.sortByScore(t, s, l);  
-        if (c)
-            for (var h = 0; h < c.length && h < a; h++) {
-                var u = c[h].item;
-                i.push(u)
-            }
-        return i
-    }
-
-    queueTilesForPanos(e, t, i, n, r) {
-        for (var o = 0, a = 0; a < t.length; a++) {
-            var s = t[a],
-                l = this.queueTilesForPano(e, i, s, n);
-            if (o += l > 0 ? 1 : 0,
-                r && o >= r)
-                break
-        }
-        return o
-    }
-
-
-    /* queueTilesInDirectionForPanos(e, t, i, n, r, o, a, s) {//没用到
-        for (var l = 0, c = 0; c < i.length; c++) {
-            var h = i[c],
-                u = this.queueTilesInDirectionForPano(e, t, h, n, o, a);
-            if (l += u > 0 ? 1 : 0,
-                s && l >= s)
-                break
-        }
-        return l
-    }
-    */
-
-    canIncludeDescriptor(e) {
-        return e.status !== DownloadStatus.Downloading && e.status !== DownloadStatus.Downloaded
-    }
-
-    canIncludePano(e, t) {
-        return !e.isLoaded(t)
-    }
-
-    getFOVDotThreshold(e) {
-        return Math.cos(THREE.Math.degToRad(e / 2))
-    }
-
-    setZoomingActive(e) {
-        e !== this.zoomingActive && (this.zoomingActive = e)
-    }
-}
-
-TilePrioritizer.PriorityCriteria = function (e, t, i, n, o) {
-    this.pano = e,
-        this.cameraPosition = (new THREE.Vector3).copy(t),
-        
-        //this.cameraDir = (new THREE.Vector3).copy(i), 
-        this.cameraDirs = [], //
-        
-        this.panoSpaceDir = (new THREE.Vector3).copy(n),
-        this.upcomingPanos = o,
-        this.copy = function (e) {
-            this.pano = e.pano,
-            this.cameraPosition.copy(e.cameraPosition),
-            //this.cameraDir.copy(e.cameraDir),
-            this.cameraDirs = e.cameraDirs
-            
-            this.panoSpaceDir.copy(e.panoSpaceDir),
-            this.upcomingPanos = o
-        },
-        this.zoomingActive = !1
-}
-
-TilePrioritizer.DIRECTIONAL_FOV = 180;
-TilePrioritizer.DIRECTIONAL_FOV_NARROW = 120;
-TilePrioritizer.MAX_SCORED_PANOS_TOCONSIDER = 6;
-TilePrioritizer.MAX_SCORED_PANOS_TOADD = 2;
-TilePrioritizer.MAX_UPCOMING_PANOS_TOADD = 3;
-TilePrioritizer.DIRECTION_SCORE_STRICTNESS = .75;
-TilePrioritizer.appendQueue = function (e, t) {
-    if (e && t)
-        for (var i = 0; i < t.length; i++){
-            e.push(t[i])
-            //console.log(t[i])
-        }
-};
-
-TilePrioritizer.sortPanoTiles = function (descriptors, pano, dir) {
-    if(dir.datasetsLocal)  dir = dir.datasetsLocal.find(e=>e.datasetId == pano.pointcloud.dataset_id).direction;//add
-    u._panoSpaceDir.copy(dir) 
-    TileUtils.getRelativeDirection(pano.quaternion4dkk, u._panoSpaceDir) //应该是将dir根据quaternion转化下
-    u._fovThresholdNarrow = math.getFOVDotThreshold(TilePrioritizer.DIRECTIONAL_FOV_NARROW)
-    u._fovThreshold = math.getFOVDotThreshold(TilePrioritizer.DIRECTIONAL_FOV) 
-    descriptors.sort(u)
-};
-
-TilePrioritizer.insertSortedPanoTile = function (e, t, pano, dir) {
-    if(dir.datasetsLocal)  dir = dir.datasetsLocal.find(e=>e.datasetId == pano.pointcloud.dataset_id).direction;//add
-    u._panoSpaceDir.copy(dir),
-        TileUtils.getRelativeDirection(pano.quaternion4dkk, u._panoSpaceDir),
-        u._fovThresholdNarrow = math.getFOVDotThreshold(TilePrioritizer.DIRECTIONAL_FOV_NARROW),
-        u._fovThreshold = math.getFOVDotThreshold(TilePrioritizer.DIRECTIONAL_FOV);
-    for (var o = -1, a = 0; a < e.length; a++) {
-        var s = u(t, e[a]);
-        if (s <= 0) {
-            o = a;
-            break
-        }
-    }
-    if (o === -1)
-        e[e.length] = t;
-    else {
-        for (var h = e.length; h > o; h--)
-            e[h] = e[h - 1];
-        e[o] = t
-    }
-};
-
-
-
-TilePrioritizer.prototype.filterDepthTex = function (panos ) {//仅下载depthTex
-    if(!Potree.settings.useDepthTex || !this.priorityCriteria.pano)return
-    
-    let cameraDirLocals = this.priorityCriteria.cameraDirs.vectorForward
-    let t = [] 
-    //获得视野范围内的邻近点位序列t
-    this.populateScoredPanos(this.priorityCriteria.pano, panos, t, cameraDirLocals , TilePrioritizer.MAX_SCORED_PANOS_TOCONSIDER);
-    
-    t.forEach(p=>p.loadDepthImg()) 
-}
-
-
-
-TilePrioritizer.prototype.filterAndPrioritize = function () {//挑选出优先加载的 pano和tile (有点复杂,没看很懂)
-    var e = [],
-        t = [],
-        i = [];
-    return function (queue, panos, tileDownloader) {
-        //this.populateNeighborPanos(this.priorityCriteria.pano, panos, e);
-         
-        /* let cameraDirLocals = this.priorityCriteria.cameraDirs.map(e=>{ //add
-            var dataset = viewer.scene.pointclouds.find(u=>u.dataset_id == e.datasetId)
-            var matrix = new THREE.Matrix4().copy(dataset.rotateMatrix)
-            var direction = math.convertVector.YupToZup(e.direction)  
-        
-        
-            return {
-                datasetId:e.datasetId,
-                direction: direction.clone().applyMatrix4(matrix)
-            }
-        }) */
-        let cameraDirLocals = this.priorityCriteria.cameraDirs.vectorForward
-         
-        //获得视野范围内的邻近点位序列t
-        this.populateScoredPanos(this.priorityCriteria.pano, panos, t, cameraDirLocals , TilePrioritizer.MAX_SCORED_PANOS_TOCONSIDER);
-        
-        t.forEach(p=>p.loadDepthImg()) //add
-        
-        var s = this.baseSize //512
-            ,
-            l = this.standardSize //1024
-            ,
-            c = this.highSize //2048
-            ,
-            h = this.ultraHighSize; //4096
-            
-            
-        this.queueTilesForPano(queue, tileDownloader, this.priorityCriteria.pano, s);  //把当前pano的512下载了
-        
-        
-        if (this.priorityCriteria.upcomingPanos) {// 添加即将走到的点(之前用于导览路线)512 tiles
-            this.queueTilesForPanos(queue, this.priorityCriteria.upcomingPanos, tileDownloader, s, TilePrioritizer.MAX_UPCOMING_PANOS_TOADD);
-        }
-        i.length = 0;
-        
-        //把当前pano角度范围内的tile按照分辨率从低到高加入队列
-        
-        if (this.canDownloadSize(l)) {//1024如果在限制范围内的话
-            this.queueTilesInDirectionForPano(i, tileDownloader, this.priorityCriteria.pano, l, this.priorityCriteria.cameraPosition, this.priorityCriteria.cameraDirs, TilePrioritizer.DIRECTIONAL_FOV_NARROW);
-        } 
-        TilePrioritizer.sortPanoTiles(i, this.priorityCriteria.pano, this.priorityCriteria.cameraDirs); //排序
-        TilePrioritizer.appendQueue(queue, i);
-        
-        //添加邻近点t 512的tiles
-        this.queueTilesForPanos(queue, t, tileDownloader, s, TilePrioritizer.MAX_SCORED_PANOS_TOADD);
-        i.length = 0;
-        
-        
-        //NARROW    :
-        if (this.canDownloadSize(c)) {//2048
-            this.queueTilesInDirectionForPano(i, tileDownloader, this.priorityCriteria.pano, c, this.priorityCriteria.cameraPosition, this.priorityCriteria.cameraDirs, TilePrioritizer.DIRECTIONAL_FOV_NARROW);
-        }
-
-        if (this.canDownloadSize(h)) {//4096
-            this.queueTilesInDirectionForPano(i, tileDownloader, this.priorityCriteria.pano, h, this.priorityCriteria.cameraPosition, this.priorityCriteria.cameraDirs, TilePrioritizer.DIRECTIONAL_FOV_NARROW);
-        } 
-        TilePrioritizer.sortPanoTiles(i, this.priorityCriteria.pano, this.priorityCriteria.cameraDirs);//排序
-        TilePrioritizer.appendQueue(queue, i);
-        i.length = 0;
-
-        if (this.canDownloadSize(l)) {//1024
-            this.queueTilesInDirectionForPano(i, tileDownloader, this.priorityCriteria.pano, l, this.priorityCriteria.cameraPosition, this.priorityCriteria.cameraDirs, TilePrioritizer.DIRECTIONAL_FOV);
-        }
-
-        if (this.canDownloadSize(c)) {//2048
-            this.queueTilesInDirectionForPano(i, tileDownloader, this.priorityCriteria.pano, c, this.priorityCriteria.cameraPosition, this.priorityCriteria.cameraDirs, TilePrioritizer.DIRECTIONAL_FOV);
-        }
-
-        if (this.canDownloadSize(h)) {//4096
-            this.queueTilesInDirectionForPano(i, tileDownloader, this.priorityCriteria.pano, h, this.priorityCriteria.cameraPosition, this.priorityCriteria.cameraDirs, TilePrioritizer.DIRECTIONAL_FOV);
-        }
-
-        TilePrioritizer.sortPanoTiles(i, this.priorityCriteria.pano, this.priorityCriteria.cameraDirs);//排序
-        TilePrioritizer.appendQueue(queue, i);
-        
-        
-        
-        this.queueTilesForPanos(queue, e, tileDownloader, s); // 如果前面有populateNeighborPanos的话,这步就是加neibour
-    }
-}()
-TilePrioritizer.prototype.queueTilesInDirectionForPano = function () {
-    var e = {
-            filter: h.DirectionalFOV,
-            direction: new THREE.Vector3,
-            fov: 60
-        },
-        t = new THREE.Vector3;
-    return function (i, n, pano, o, a, dirs, c) {
-        
-        var dir = dirs.datasetsLocal.find(e=>e.datasetId == pano.pointcloud.dataset_id).direction;//add
-        //var dir = dirs
-        
-        t.copy(dir);
-        
-        TileUtils.getRelativeDirection(pano.quaternion4dkk, t);
-        e.direction.copy(t);
-        e.fov = c;
-        return this.filterAndQueueTileDownloadDescriptors(i, n, pano, o, e)
-    }
-}()
-
-TilePrioritizer.prototype.filterAndQueueTileDownloadDescriptors = function () {
-    var e = [];
-    return function (t, i, n, r, o) {
-        var a = i.getTileDownloadDescriptors(n, r);
-        e.length = 0,
-            this.filterTileDownloadDescriptors(n, a, e, o);
-        for (var s = 0, l = 0; l < e.length; l++) {
-            var c = e[l];
-            if (c) {
-                t.push(c);
-                s++;
-            }
-        }
-        return s
-    }
-}()
-
-TilePrioritizer.prototype.filterTileDownloadDescriptors = function () {
-    new THREE.Vector3;
-    return function (e, t, i, n) {
-        var r, o;
-        switch (n.filter) {
-            case h.DirectionalFOV:
-                for (r = 0; r < t.length; r++)
-                    o = t[r],
-                    TileUtils.isTileWithinFOV(o.panoSize, o.tileSize, o.face, o.tileX, o.tileY, n.direction, n.fov) && i.push(o);
-                break;
-            default:
-                for (r = 0; r < t.length; r++)
-                    o = t[r],
-                    i.push(o)
-        }
-        for (r = 0; r < i.length; r++)
-            o = i[r],
-            this.canIncludeDescriptor(o) || (i[r] = null)
-    }
-}()
-TilePrioritizer.prototype.queueTilesForPano = function () {
-    var e = {
-        filter: h.None
-    };
-    return function (t, i, n, r) {
-        return this.filterAndQueueTileDownloadDescriptors(t, i, n, r, e)
-    }
-}()
-
-
-
-/* TilePrioritizer.prototype.queueTilesForPanosInDirection = function () { //没用到
-    var e = new THREE.Vector3;
-    return function (t, i, n, r, o, a, s, l) {
-        for (var h = 0, u = 0; u < n.length; u++) {
-            var d = n[u];
-            e.copy(d.position),
-                e.sub(o),
-                e.normalize();
-            var p = Math.max(Math.min(a.dot(e), 1), -1),
-                f = c.getFOVDotThreshold(s);
-            if (p >= f) {
-                var g = this.queueTilesInDirectionForPano(t, i, d, r, o, a, s);
-                if (h += g > 0 ? 1 : 0,
-                    l && h >= l)
-                    break
-            }
-        }
-        return h
-    }
-}() */
-

+ 0 - 168
src/modules/Images360/tile/TileTree.js

@@ -1,168 +0,0 @@
-import * as THREE from "../../../../libs/three.js/build/three.module.js";
-
-
-function Node(e, t) {
-    this.tree = e,  //所属树(TileTree)
-    this.parent = t,
-    this.children = [],
-    this.id = ++u;
-}
-
-function o(e, t, i, r, a, s, l, h) {
-    if (e) {
-        l = l || TileTree.TraversalType.PreOrder;
-        var u = r * c + i;
-        if (l === TileTree.TraversalType.PreOrder && (a && a(e, t, u, i, r),
-                s && s.push(e)),
-            e.children && 0 !== e.children.length) {
-            for (var d = r * c, p = i * c, f = 0; f < c; f++)
-                for (var g = 0; g < c; g++)
-                    o(e.children[g * c + f], t + 1, p + f, d + g, a, s, l, h);
-            l === TileTree.TraversalType.PostOrder && (a && a(e, t, u, i, r),
-                s && s.push(e))
-        }
-    }
-}
-
-function Plant(seed) {
-    seed.root = Branch(seed, null, 0)
-}
-
-function Branch(seed, parent, level) {
-    if (level > seed.levels)
-        return null;
-    var node = new Node(seed, parent);
-    seed.allNodes.push(node);
-    for (var o = 0; o < h; o++)
-        node.children[o] = Branch(seed, node, level + 1);
-    return node
-}
-
-function l(parent, t, level, n, r) {
-    if (!parent)
-        return null;
-    if (0 === level)
-        return parent;
-    if (!parent.children || 0 === parent.children.length)
-        return null;
-    var o = Math.pow(c, level),
-        a = o / c,
-        s = n % a,
-        h = r % a,
-        u = Math.floor(r / a),
-        d = Math.floor(n / a),
-        p = u * c + d,
-        f = parent.children[p];
-    return l(f, t + 1, level - 1, s, h)
-}
-
-
-/*  cube每个面都有一个分层树  用于代表瓦片图的细分?
-
-    树4096的分为三层,每层有4个子节点。(最后一层的四个子节点都是null)
-
- */
- 
- 
-var c = 2,
-    h = c * c; //4个子节点
-var u = 0;
-
-
-
-
-export default class TileTree {
-    constructor(e, t) {
-        this.levels = t,
-        this.tileSize = e,
-        this.root = null,
-        this.allNodes = [],
-        Plant(this);
-    }
-
-    getSubNode(e, t, i) {
-        (!t || e < this.tileSize) && (t = 0),
-        (!i || e < this.tileSize) && (i = 0),
-        e < this.tileSize && (e = this.tileSize);
-        var level = TileTree.getLevelCountForSize(this.tileSize, e),
-            o = l(this.root, 0, level, t, i);
-        return o
-    }
-
-    breadthFirst(e) {//广度优先搜索
-        e = e || {};
-        var t = !!e.nullLevelEnd,
-            i = e.maxLevel,
-            n = e.minLevel,
-            r = e.callback,
-            o = e.saveVisited,
-            a = [],
-            s = {},
-            l = 0,
-            c = 0;
-        for (a.push(this.root),
-            a.push(s); a.length > 0 && !(i && l > i);) {
-            var h = a.shift();
-            if (h === s)
-                (!n || l >= n) && (r && t && r(null),
-                    o && t && o.push(null)),
-                a.length > 0 && a.push(s),
-                l++,
-                c = 0;
-            else {
-                if (h.children)
-                    for (var u = 0; u < h.children.length; u++) {
-                        var d = h.children[u];
-                        d && a.push(h.children[u])
-                    }
-                var p = this.getFaceIndexFromNode(h);
-                (!n || l >= n) && (r && r(h, l, p),
-                    o && o.push(h)),
-                c++
-            }
-        }
-    }
-
-    getFaceIndexFromNode(e) {
-        if (!e)
-            return -1;
-        for (var t = 1, i = e, n = 0, r = 0;;) {
-            var o = i.parent;
-            if (!o)
-                break;
-            for (var a = -1, s = 0; s < o.children.length; s++)
-                o.children[s] === i && (a = s);
-            var l = a % c,
-                h = Math.floor(a / c);
-            n = l * t + n,
-                r = h * t + r,
-                t *= c,
-                i = o
-        }
-        return r * t + n
-    }
-
-    depthFirst(e, t, i) {
-        o(this.root, 0, 0, 0, e, t, i, this.tileSize)
-    }
-}
-
-TileTree.TraversalType = Object.freeze({
-    PreOrder: 0,
-    PostOrder: 1
-});
-
-TileTree.getLevelCountForSize = function(tileSize, size) {//512->0 2024->1
-    var i = 0;
-    for (size < tileSize && (size = tileSize);;) {
-        if (size /= c,
-            size < tileSize)
-            break;
-        i++
-    }
-    return i
-};
-
-TileTree.getSizeForLevel = function(e, t) {
-    return Math.pow(c, t) * e
-};

+ 0 - 283
src/modules/Images360/tile/TileUtils.js

@@ -1,283 +0,0 @@
-import {GLCubeFaces} from '../../../defines.js'
-import MathLight from '../../../utils/MathLight.js'
-import * as THREE from "../../../../libs/three.js/build/three.module.js";
-
-
-
-var TileUtils = {};
-TileUtils.TILE_SIZE = 512,
-TileUtils.FACES_PER_PANO = 6,
-TileUtils.LocationOnTile = {
-    Center: 0,
-    UpperLeft: 1,
-    UpperRight: 2,
-    LowerRight: 3,
-    LowerLeft: 4
-},
-
-
-/*
- * 获取某tile在cube中的方向 direction (向量起点在cube中心,终点在tile图的指定位置)。spherical通过先求uv,再直接得到dir
- * @param {*} size 面分辨率
- * @param {*} cubeFace 所在面
- * @param {*} Center 在tile上的目标位置,默认为中心,其他位置就是四个顶点
- * @param {*} c 似乎是在tile的缩进百分比,根据所在面的不同,分别向不同方向缩进,但都是向tile的中心
- * @param {*} dir 所求方向
- */
-
-TileUtils.getTileVector = function() {//获取某tile在cube中的方向 direction (向量起点在cube中心,终点在tile图的中心)
-    return function(size, tileSize, cubeFace, tileX, tileY, Center, c, dir) {//c似乎是缩进百分比
-       
-        Center = Center || TileUtils.LocationOnTile.Center;
-        
-        //假设该cube边长为2:
-        var u = size / tileSize
-            , d = tileX / u;
-        tileY = -tileY + (u - 1);
-        var p = tileY / u
-            , f = tileSize / size
-            , g = 2 * f //一个tile的宽度   (乘以2是因为cube边长是2)
-            , m = g / 2
-            , v = 2 * d - 1 + m
-            , A = 2 * p - 1 + m;
-            
-        switch (Center) {//计算在tile中指定位置带来的偏移 
-            case TileUtils.LocationOnTile.UpperLeft:        //1
-                v -= m,
-                A += m,
-                v += c * g; //似乎是向内缩进
-                break;
-            case TileUtils.LocationOnTile.UpperRight:
-                v += m,
-                A += m,
-                A -= c * g;
-                break;
-            case TileUtils.LocationOnTile.LowerRight:
-                v += m,
-                A -= m,
-                v -= c * g;
-                break;
-            case TileUtils.LocationOnTile.LowerLeft:
-                v -= m,
-                A -= m,
-                A += c * g;
-                break;
-            case TileUtils.LocationOnTile.Center:   //0
-        }
-        switch (cubeFace) {
-            case GLCubeFaces.GL_TEXTURE_CUBE_MAP_POSITIVE_X:
-                MathLight.setVector(dir, -1, A, -v);
-                break;
-            case GLCubeFaces.GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
-                MathLight.setVector(dir, 1, A, v);
-                break;
-            case GLCubeFaces.GL_TEXTURE_CUBE_MAP_POSITIVE_Y: //顶面
-                MathLight.setVector(dir, -v, 1, -A);
-                break;
-            case GLCubeFaces.GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
-                MathLight.setVector(dir, -v, -1, A);
-                break;
-            case GLCubeFaces.GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
-                MathLight.setVector(dir, -v, A, 1);
-                break;
-            case GLCubeFaces.GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
-                MathLight.setVector(dir, v, A, -1)
-        }
-        MathLight.normalize(dir)
-    }
-}(),
-
-/*
- * 获取该tile在第几个面(简易装载法) 
- */
-TileUtils.getFaceForTile = function(size, index) {//获取该tile在第几个面
-    var tileSize = TileUtils.TILE_SIZE;
-    size < TileUtils.TILE_SIZE && (tileSize = size);
-    var n = Math.floor(size / tileSize)
-        , sum = n * n; //得每个面tile总数
-    return Math.floor(index / sum)
-}
-,
-
-
-TileUtils.getTileLocation = function(size, t, result) {
-    var tileSize = TileUtils.TILE_SIZE;
-    size < TileUtils.TILE_SIZE && (tileSize = size);
-    var r = TileUtils.getFaceForTile(size, t)
-        , a = Math.floor(size / tileSize)
-        , s = a * a
-        , l = t - r * s;
-    result.tileX = l % a;
-    result.tileY = Math.floor(l / a);
-    result.face = r;
-    result.faceTileIndex = l;
-    return result
-}
-,
-
-/*
- * 求size分辨率需要多少张tile
- */
-TileUtils.getTileCountForSize = function(e) {
-    if (e <= TileUtils.TILE_SIZE)
-        return TileUtils.FACES_PER_PANO;
-    var t = Math.floor(e / TileUtils.TILE_SIZE)
-        , i = t * t
-        , n = i * TileUtils.FACES_PER_PANO;
-    return n
-}
-,
-TileUtils.getRelativeDirection = function() {
-    var e = new MathLight.Matrix4
-        , t = new MathLight.Quaternion;
-    return function(i, n) {//i是pano.quaternion,  n是camera的direction  
-        t.copy(i),
-        t.inverse(),
-        e.makeRotationFromQuaternion(t),
-        e.applyToVector3(n),
-        MathLight.normalize(n)
-    }
-}(),
-
-/*
- * 根据方向寻找合适的tile加载
- */
-TileUtils.matchingTilesInDirection = function() {
-    var e = new MathLight.Vector3
-        , t = new MathLight.Vector3(0,0,-1)
-        , i = new MathLight.Quaternion
-        , n = function(e, t) {
-            e.push({
-                face: t.face,
-                faceTileIndex: t.faceTileIndex,
-                tileX: t.tileX,
-                tileY: t.tileY
-            })
-        }
-        , a = function() {
-            var e = {
-                face: -1,
-                faceTileIndex: -1,
-                tileX: -1,
-                tileY: -1
-            };
-            return function(size, i, r) {
-                for (var a = TileUtils.getTileCountForSize(size), s = 0, l = 0; l < a; l++)
-                    TileUtils.getTileLocation(size, l, e),
-                    i && !i(e) || (s++,
-                    r && n(r, e));
-                return s
-            }
-    }();
-    return function(pano, size, dir, hFov, vFov, result) {
-        var d = size < TileUtils.TILE_SIZE ? size : TileUtils.TILE_SIZE;
-        //TileUtils.getTileCountForSize(size);
-        if (!hFov && !vFov)
-            return a(size, null, result);
-        var p = !!vFov;
-        vFov = vFov || hFov,
-        vFov = Math.max(0, Math.min(vFov, 360)),
-        hFov = Math.max(0, Math.min(hFov, 360)),
-        MathLight.copyVector(dir, e),
-        TileUtils.getRelativeDirection(pano.quaternion4dkk, e)
-        if(p){//如果有vFov hFov
-            i.setFromUnitVectors(e, t);
-            var f = function(e) {
-                return TileUtils.isTileWithinFrustum(size, d, e.face, e.tileX, e.tileY, i, hFov, vFov)//在视野中的
-            };
-            return a(size, f, result)
-        }
-        var g = function(t) {//如果仅有hFov
-            return TileUtils.isTileWithinFOV(size, d, t.face, t.tileX, t.tileY, e, hFov)
-        };
-        return a(size, g, result)
-    }
-}(),
-
-/*
- * 是否在屏幕范围内
- */ 
-TileUtils.isTileWithinFrustum = function() {
-    var e = new MathLight.Vector3
-        , t = 1e-5;
-    return function(i, n, a, s, l, c, h, u) {
-        for (var d = Math.tan(.5 * u * MathLight.RADIANS_PER_DEGREE), p = -d, f = Math.tan(.5 * h * MathLight.RADIANS_PER_DEGREE), g = -f, m = TileUtils.mapFaceToCubemapFace(a), v = 0, A = 0, y = 0, C = 0, I = 0, E = 0, b = TileUtils.LocationOnTile.Center; b <= TileUtils.LocationOnTile.LowerLeft; b++){
-            TileUtils.getTileVector(i, n, m, s, l, b, 0, e),//get e   //  size, tileSize, cubeFace, tileX, tileY, Center, c, dir
-            MathLight.applyQuaternionToVector(c, e)      
-            if (e.z >= -t)//似乎是在相机背面
-                I++;
-            else { 
-                var w = -1 / e.z
-                    , _ = e.x * w
-                    , T = e.y * w;
-                T > d ? v++ : T < p && A++,  //这四种似乎代表在这个画框之外,如在左、在上、在下、在右
-                _ > f ? y++ : _ < g && C++,
-                E++
-            }
-        }
-        return A !== E && v !== E && y !== E && C !== E  //如果有一项和E相等代表要么是在相机背面要么是tile的四个顶点都画在画布的同一边,所以肯定不在画布上
-    }
-}(),
-
-
-/*
- * 是否在FOV范围内
- */
-TileUtils.isTileWithinFOV = function() {
-    var e = new MathLight.Vector3
-        , t = new MathLight.Vector3(0,1,0)
-        , i = new MathLight.Vector3(1,0,0);
-    return function(panoSize, tileSize, face, tileX, tileY, direction, fov) {//direction是作用了pano.quaternion的camera.direction
-        var d = TileUtils.mapFaceToCubemapFace(face);
-        MathLight.cross(direction, t, i) //get i  好像没用到
-        TileUtils.getTileVector(panoSize, tileSize, d, tileX, tileY, TileUtils.LocationOnTile.Center, 0, e) 
-        if (TileUtils.isWithinFOV(e, direction, fov, null))//先判断tile中心在不在FOV内
-            return !0;
-        for (var p = fov / 360, f = Math.floor(1 / p), g = 0, m = 0; m < f; m++) {
-            for (var v = TileUtils.LocationOnTile.UpperLeft; v <= TileUtils.LocationOnTile.LowerLeft; v++)
-                if (TileUtils.getTileVector(panoSize, tileSize, d, tileX, tileY, v, g, e),
-                TileUtils.isWithinFOV(e, direction, fov, null))
-                    return !0;
-            g += p   //可能是考虑到有可能tile比fov覆盖了fov(虽然一般不可能,除非fov特别小),所以将tile分成若干段,取tile中的点再检测下
-        }
-        return !1
-    }
-}(),
-
-
-TileUtils.isWithinFOV = function() {
-    var e = new MathLight.Vector3
-        , t = new MathLight.Vector3;
-    return function(dir, cameraDir, fov, a) {
-        if (MathLight.copyVector(dir, t),
-        a) {
-            MathLight.copyVector(a, e),
-            MathLight.normalize(e);
-            var s = MathLight.dot(e, dir);
-            e.x *= s,
-            e.y *= s,
-            e.z *= s,
-            MathLight.subVector(t, e)
-        }
-        var l = fov / 2 * MathLight.RADIANS_PER_DEGREE
-            , c = Math.cos(l)
-            , h = MathLight.dot(t, cameraDir);
-        return h >= c
-    }
-}(),
-
-TileUtils.mapFaceToCubemapFace = function() {
-    var e = {
-        0: GLCubeFaces.GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
-        1: GLCubeFaces.GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
-        2: GLCubeFaces.GL_TEXTURE_CUBE_MAP_POSITIVE_X,
-        3: GLCubeFaces.GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,
-        4: GLCubeFaces.GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
-        5: GLCubeFaces.GL_TEXTURE_CUBE_MAP_NEGATIVE_Y
-    };
-    return function(t) {
-        return e[t]
-    }
-}();
-
-export default TileUtils

+ 0 - 253
src/modules/Particles/ParticleEditor.js

@@ -1,253 +0,0 @@
-
-import * as THREE from "../../../libs/three.js/build/three.module.js";
-import FireParticle from '../../objects/fireParticle/fire/FireParticle.js'
-import SmokeParticle from '../../objects/fireParticle/smoke/SmokeParticle.js'
-import ExplodeParticle from '../../objects/fireParticle/explode/ExplodeParticle.js'
-import CurveCtrl from '../../objects/tool/CurveCtrl.js'
-import {LineDraw} from "../../utils/DrawUtil.js";
-import Common from '../../utils/Common.js'
-import {ExtendEventDispatcher} from "../../custom/ExtendEventDispatcher.js";
-import DepthBasicMaterial from "../../materials/DepthBasicMaterial.js";
-
-
-
-const colors = {
-    'fire+smoke':0xffffff,
-    'smoke': 0xffffff,
-    'explode':0xffffff,
-}
-
-
-let depthMatPrefix = {
-    clipDistance : 100, occlusionDistance:60, /* 变为backColor距离 */ 
-    maxClipFactor:0.5, backColor:"#777"  ,
-    useDepth:true, transparent: !0,
-}
-let lineMats; 
-let getLineMat = function(type){
-    if(!lineMats){
-        lineMats = {
-            'fire+smoke':LineDraw.createFatLineMat($.extend(depthMatPrefix,{  
-                color: colors['fire+smoke'],  
-                lineWidth: 2 
-            })),
-            'smoke' :LineDraw.createFatLineMat($.extend(depthMatPrefix,{  
-                color: colors['smoke'],  
-                lineWidth: 2   
-            })),
-            'explode' :LineDraw.createFatLineMat($.extend(depthMatPrefix,{  
-                color: colors['explode'],  
-                lineWidth: 2 
-            })),           
-        }        
-    }
-    return lineMats[type]
-}
-
-let handleMats
-let getHandleMat = function(type){ 
-    if(!handleMats){
-        let texLoader = new THREE.TextureLoader()
-        
-        handleMats = {   
-            "fire+smoke" :   new DepthBasicMaterial($.extend(depthMatPrefix,{  
-                map: texLoader.load(Potree.resourcePath+'/textures/icon-fire.png' ), 
-                color:  colors['fire+smoke'],                
-            })),
-            "smoke" :   new DepthBasicMaterial($.extend(depthMatPrefix,{     
-                map: texLoader.load(Potree.resourcePath+'/textures/icon-smoke.png' ),  
-                color:  colors['smoke'],              
-            })),
-            "explode" :   new DepthBasicMaterial($.extend(depthMatPrefix,{   
-                map: texLoader.load(Potree.resourcePath+'/textures/icon-explode.png' ), 
-                color:  colors['explode'],      
-            })), 
-        } 
-    }
-    return handleMats[type]
-}
-
-let ParticleEditor = {
-    
-    bus: ExtendEventDispatcher,
-    particleGroup : new THREE.Object3D ,
-    curveGroup:new THREE.Object3D ,
-    init:function(){
-        this.particleGroup.name = 'particles'
-        viewer.scene.scene.add( this.particleGroup );
-        
-        
-        this.curveGroup.name = 'particles-curves'
-        viewer.scene.scene.add( this.curveGroup );
-        
-        
-    },
-    addParticle : function(prop={}){
-        
-         
-        let particle
-        if(prop.type == 'fire'){ 
-            particle = new FireParticle(prop) 
-            
-        }else if(prop.type == 'smoke'){
-            particle = new SmokeParticle(prop) 
-            
-        }else if(prop.type == 'explode'){
-            particle = new ExplodeParticle(prop) 
-        }
-        
-        this.particleGroup.add(particle)
-         
-        
-        
-        return particle
-    }
-    ,
-    removeParticle(particle){
-        //particle.dispatchEvent('delete')
-        particle.dispose();
-        this.particleGroup.remove(particle)
-        particle.curve.dispose()
-    }
-    ,
-    update(delta){
-        this.particleGroup.children.forEach(e=>e.update(delta))
-    }
-    ,
-    
-    startInsertion(type = 'fire', prop={}){  //viewer.modules.ParticleEditor.startInsertion()
-        let deferred = $.Deferred();
-        let particles = [];
-        
-        let finish = (ifDone)=>{ 
-            if(ifDone){
-                deferred.resolve(particles) 
-            }
-            viewer.dispatchEvent({
-                type : "CursorChange", action : "remove",  name:"addSth"
-            }); 
-            viewer.removeEventListener('global_click', click) 
-            this.bus.removeEventListener('cancel_insertions',cancel)
-        }
-        
-        let curve = new CurveCtrl([], getLineMat(type), colors[type], type+'_curve', {handleMat:getHandleMat(type)} )
-        this.curveGroup.add(curve)
-        prop.curve = curve
-        prop.type = type 
-        //console.log('创建curve',type,curve.uuid)
-        
-        let cancel = ()=>{
-            console.log('cancel_insertions', curve.uuid )
-            curve.dispose();
-            finish(false)
-        }
-        this.bus.dispatchEvent('cancel_insertions')//删除旧的
-        this.bus.addEventListener('cancel_insertions',cancel)
-        
-        var click = (e)=>{  
-            if(e.button === THREE.MOUSE.RIGHT){  
-                if(curve.points.length>=1){ //if(type.includes('fire') || type.includes('smoke')  ){ 
-                      
-                    particles = this.createFromData(prop) 
-                    finish(true)                        
-                } 
-                return  
-            }
-            
-             
-            var I = e.intersect && (e.intersect.orthoIntersect || e.intersect.location)
-            if(!I)return
-            
-            curve.addPoint(I, null, true) 
-            
-            if(type == 'explode'){ 
-                particles = this.createFromData(prop)   
-                
-                finish(true)
-            }
-            
-            return {stopContinue:true}//防止继续执行别的侦听,如flytopano
-        }
-     
-        
-        viewer.addEventListener('global_click', click, 10)//add importance:10
-        viewer.dispatchEvent({
-            type : "CursorChange", action : "add",  name:"addSth"
-        });
-        
-        return deferred.promise()
-    },
-    
-    
-    
-    createFromData(prop){
-        const type = prop.type;
-        var particles = []
-        let curve = prop.curve;
-        if(!curve){
-            curve = new CurveCtrl(prop.points, getLineMat(type), colors[type], type+'_curve', {handleMat:getHandleMat(type)} )
-            this.curveGroup.add(curve)
-        }
-        
-        if(type.includes('fire') || type.includes('smoke')  ){
-            if(type.includes('fire')){
-                var fire = this.addParticle({
-                    type : 'fire',
-                    positions : curve.points,
-                    curve,
-                    radius : prop.radius,
-                    height: prop.height,
-                    strength : prop.strength,
-                })
-                particles.push(fire)
-            }
-            if(type.includes('smoke')){ 
-                var smoke = this.addParticle({
-                    type : 'smoke', 
-                    positions : curve.points,
-                    curve,
-                    positionStyle : 'sphere' , 
-                    strength : prop.smokeStrength,
-                    radius: prop.smokeRadius,
-                    height: prop.smokeHeight,
-                })
-                particles.push(smoke)
-            }
-             
-            
-        }else if(type == 'explode'){
-            var explode = this.addParticle({
-                type : 'explode', 
-                position : curve.points[0],
-                strength: prop.strength,
-                radius : prop.radius,
-                particleSpaceTime: prop.particleSpaceTime,
-                curve,
-                delayStartTime:prop.delayStartTime,
-            })
-            particles.push(explode)
-        }    
-
-        var geoNeedsUpdate 
-        curve.addEventListener('dragCurvePoint',()=>{ 
-            geoNeedsUpdate = true 
-            Common.intervalTool.isWaiting('particlePointChange', ()=>{ //延时update,防止卡顿  
-                if(geoNeedsUpdate){ 
-                    particles.forEach(e=>e.updateGeometry())  
-                    geoNeedsUpdate = false 
-                    curve.dispatchEvent('sendUpdatePoints')
-                    return true  
-                }
-            }, 400)  
-        })
-        
-        
-        
-        
-        return particles
-    }
-}
-
-
-
-export default ParticleEditor

+ 0 - 343
src/modules/clipModel/Clip.js

@@ -1,343 +0,0 @@
-import * as THREE from "../../../libs/three.js/build/three.module.js";
-import {BoxVolume} from '../../objects/tool/Volume.js'
-import {  ClipTask, ClipMethod} from "../../defines.js"
-import {mapClipBox} from '../../objects/tool/mapClipBox.js'
-import Common from '../../utils/Common.js'
-import math from '../../utils/math.js' 
-import {Images360} from '../Images360/Images360.js' 
-import {ExtendEventDispatcher} from "../../custom/ExtendEventDispatcher.js";
-
-const defaultBoxWidth = 6;  //navvis:  10
-                            //navvis position: si {x: 0, y: 0, z: 0}
-   
-var Clip = {
-    bus : new ExtendEventDispatcher,
-    selectedDatasets : [],    
-    changeCallback(force){ 
-        if(Potree.settings.isOfficial){  
-            Common.intervalTool.isWaiting('clipSelectedDatasets', ()=>{ //延时update,防止卡顿
-                let pointclouds = this.getIntersectPointcloud() 
-                if(force || Common.getDifferenceSet(pointclouds,this.selectedDatasets).length){  
-                    this.selectedDatasets = pointclouds 
-                    //console.error('clipSelectedDatasets',selectedDatasets)
-                    this.bus.dispatchEvent({type:'updateSelectedDatasets', selectedDatasets:pointclouds.map(e=>e.dataset_id) })
-                    force = false
-                    return true 
-                } 
-            },  300)  
-        } 
-    },
-
-    enter:function(){
-        this.previousView = { 
-			position: viewer.images360.position,
-			target: viewer.scene.view.getPivot(),
-            displayMode : Potree.settings.displayMode,
-            //---
-            ifShowMarker : Potree.settings.ifShowMarker,
-            
-		} 
-
-        let pointcloud = this.getPointcloud() 
-        let bound = pointcloud.bound //只选取其中一个数据集的bound,而非整体,是因为担心两个数据集中间有空隙,于是刚好落在没有点云的地方。
-        let boundSize = bound.getSize(new THREE.Vector3())
-        let target = this.getTarget(bound.getCenter(new THREE.Vector3())); //navvis的位置xy是用相机位置 this.ViewService.mainView.getCamera().position  我觉得也可以用第一个漫游点的,或者最接近bound中心的漫游点
-        let scale = new THREE.Vector3(defaultBoxWidth,defaultBoxWidth, boundSize.z)//z和navvis一样
-        
-        let eyeDir = viewer.scene.view.direction.clone().setZ(0/* -boundSize.z/3 */).multiplyScalar(-defaultBoxWidth)  //为了使所在楼层不变,不修改z
-
-        //let eyeDir = scale.clone().setZ(boundSize.z/3).multiplyScalar(1.3) 
-        let position = new THREE.Vector3().addVectors(target, eyeDir)
-        
-        Potree.settings.displayMode = 'showPointCloud'
-        viewer.setView({
-            position ,
-            target,
-            duration:300,
-            callback:function(){ 
-            }
-        })
-        viewer.setControls(viewer.orbitControls);
-        viewer.setLimitFar(false)
-         
-        
-        
-        {
-            this.box = new BoxVolume({
-                clip:true
-                
-            })  
-            this.box.name = "ClipBox"; 
-            this.box.position.copy(target)
-            this.box.scale.copy(scale)
-            //带动mapBox
-            this.box.addEventListener('position_changed',e=>{
-                this.mapBox.center.setX(this.box.position.x)
-                this.mapBox.center.setY(this.box.position.y)
-                this.mapBox.updatePoints() 
-                this.changeCallback()
-            })
-            this.box.addEventListener('scale_changed',e=>{
-                var scale = this.box.scale 
-                this.mapBox.updatePoints(scale)
-                this.changeCallback()
-            })
-            this.box.addEventListener('orientation_changed',e=>{
-                this.mapBox.angle = this.box.rotation.z
-                this.mapBox.rotateBar.rotation.z = this.mapBox.angle
-                this.mapBox.updatePoints()
-                this.changeCallback()
-            })
-            viewer.scene.addVolume(this.box);
-            
-        }
-        
-        {//map
-            let boxRotateBack = ()=>{//不知道是不是这么写。 因为可能z的旋转不一定都在z 
-                this.box.rotation.x = 0;
-                this.box.rotation.y = 0;
-            }
-            this.mapBox = new mapClipBox(target, scale)
-            viewer.mapViewer.scene.add(this.mapBox)
-            //带动box
-            this.mapBox.addEventListener('repos',e=>{
-                this.box.position.setX(this.mapBox.center.x)
-                this.box.position.setY(this.mapBox.center.y)
-                boxRotateBack()
-                this.changeCallback()
-            })
-            this.mapBox.addEventListener('dragChange',e=>{
-                var scale = this.mapBox.getScale() 
-                this.box.scale.setX(scale.x)
-                this.box.scale.setY(scale.y)
-                this.box.position.setX(this.mapBox.center.x)
-                this.box.position.setY(this.mapBox.center.y)
-                boxRotateBack()
-                this.changeCallback()
-            })
-            this.mapBox.addEventListener('rotate',e=>{ 
-                this.box.rotation.z = this.mapBox.angle 
-                boxRotateBack()
-                this.changeCallback()
-            })
-        }
-        
-        
-        
-        
-        {
-            viewer.setClipTask(ClipTask["SHOW_INSIDE"])
-            //viewer.setClipMethod(ClipMethod["INSIDE_ANY"])  
-        }
-        
-        Potree.settings.unableNavigate = true
-        Potree.settings.ifShowMarker = false
-        viewer.updateVisible(viewer.measuringTool.scene, 'clipModel', false)   
-        //viewer.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 
-        viewer.setPointStandardMat(true) 
-        
-        {
-            this.events = {
-                flyToPos : (e)=>{ 
-                    let dis = 2
-                    let target = e.position
-                    //position = new THREE.Vector3().subVectors(target, this.scene.view.direction)
-                    
-                    //永远朝向框的中心
-                    /* let dir = new THREE.Vector3().subVectors(this.box.position, e.position).normalize()
-                    position = new THREE.Vector3().subVectors(target, dir) */
-                    
-                  
-                    target = this.box.position
-                    position = e.position
-                    //为了方便缩放操作,直接使用box中心作为target
-                    
-                    
-                    let duration = 1000
-                    viewer.scene.view.setView({position,  duration,  target})
-                } 
-            }
-            
-            this.bus.addEventListener('flyToPos',this.events.flyToPos) 
-        }
-        this.editing = true
-        
-        setTimeout(()=>{this.changeCallback(true)},1)
-    },
-    
-    leave:function(){
-        viewer.inputHandler.fixSelection = false
-        viewer.scene.removeVolume(this.box);
-        
-        this.mapBox.dispose()
-        viewer.setControls(viewer.fpControls);
-        
-        Potree.settings.unableNavigate = false
-        Potree.settings.ifShowMarker = this.previousView.ifShowMarker
-        viewer.updateVisible(viewer.measuringTool.scene, 'clipModel', true)  
-        //viewer.updateVisible(viewer.mapViewer.cursor, 'clipModel', true) 
-        viewer.setView(this.previousView)
-        viewer.setLimitFar(true)
-        viewer.setPointStandardMat(false) 
-        
-        
-        {
-            this.bus.removeEventListener('flyToPos',this.events.flyToPos) 
-            this.events = null 
-        }
-        this.editing = false
-    },
-    
-
-
-    getPointcloud:function(){ //找一个离当前最近的点云,且最好有漫游点
-        let pointclouds = viewer.scene.pointclouds.filter(e=>e.panos.length>0)
-        if(pointclouds.length == 0)pointclouds = viewer.scene.pointclouds;
-
-
-        let result = Common.sortByScore(pointclouds,[],[e=>{
-            let center = e.bound.getCenter(new THREE.Vector3)
-            let size = e.bound.getSize(new THREE.Vector3).length() / 2 
-            let posToCenter = viewer.images360.position.distanceTo(center)
-            return size / posToCenter 
-        }])
-        
-        return result[0].item
-    },
-    
-
-    getTarget:function(boundCenter){//box位置。要找一个有点云的地方。方案1相机位置, 方案2接近相机的漫游点, 方案3接近中心的漫游点。选择方案2,因最大概率有点云
-        var target = new THREE.Vector3()
-        var cameraPos = viewer.images360.position;
-        var pano = Common.find(viewer.images360.panos , [], [Images360.sortFunctions.floorDisSquaredToPoint(cameraPos)]);
-        if(pano){
-            target.copy(pano.position) 
-            target.setZ(boundCenter.z)
-        }else{
-            target.copy(boundCenter)
-        }
-        
-        return target
-    },
-    /* switchMap:function(state){
-        
-        
-    }, */
-    
-    download:function( ){
-        
-        if(this.getIntersectPointcloud().length == 0){
-            return null
-        }
-        
-        
-        var visiPointclouds = viewer.scene.pointclouds.filter(e=> viewer.getObjVisiByReason(e, 'datasetSelection'))
-        let data = {   
-            transformation_matrix: visiPointclouds.map((cloud)=>{
-                let data = {
-                    id: cloud.dataset_id, 
-                    matrix : this.getTransformationMatrix(cloud).elements, 
-                    modelMatrix:(new THREE.Matrix4).copy(cloud.transformMatrix).transpose().elements
-                }  
-                return data
-            }) ,
-            aabb: "b-0.5 -0.5 -0.5 0.5 0.5 0.5" //剪裁空间( 所有点在乘上这个矩阵后, 还能落在 1 * 1 * 1的box内的点就是所裁剪的
-           
-        }
-        
-        return data
-        //https://testlaser.4dkankan.com/indoor/t-ia44BhY/api/pointcloud/crop
-    },
-    
-    
-    
-    downloadNoCrop(){//不剪裁  下载整个点云
-        
-        var visiPointclouds = viewer.scene.pointclouds.filter(e=> viewer.getObjVisiByReason(e, 'datasetSelection'))
-        let data = {   
-            transformation_matrix: visiPointclouds.map((cloud)=>{
-                let data = {
-                    id: cloud.dataset_id, 
-                    matrix : new THREE.Matrix4().elements, //固定值
-                    modelMatrix:(new THREE.Matrix4).copy(cloud.transformMatrix).transpose().elements
-                }  
-                return data
-            }) ,
-            aabb: "b-12742000 -12742000 -12742000 12742000 12742000 12742000" //固定剪裁空间 
-           
-        }
-        console.log(data)
-        return data
-         
-        
-        
-    },
-    
-    
-    getTransformationMatrix:function(pointcloud) {//剪裁矩阵
-        var invMatrix = new THREE.Matrix4().getInverse(this.box.matrixWorld) 
-        return (new THREE.Matrix4).multiplyMatrices(invMatrix, pointcloud.transformMatrix).transpose()
-    },
-
-
-    getIntersectPointcloud(){ 
-        var boxBound = new THREE.Box3(
-            new THREE.Vector3(-0.5,-0.5,-0.5), new THREE.Vector3(0.5,0.5,0.5),
-        ).applyMatrix4(this.box.matrixWorld)    //large boundingbox
-        
-       /*  var boxTightPoints = this.box.children[0].geometry.vertices.map(e=>e.clone().applyMatrix4(this.matrixWorld)) 
-            console.log(boxTightPoints) 
-        */
-        
-        let boxMatrixInverse = new THREE.Matrix4().copy(this.box.matrixWorld).invert();
-
-        let boxPoints = [
-            new THREE.Vector3(boxBound.min.x, boxBound.min.y,0),
-            new THREE.Vector3(boxBound.max.x, boxBound.min.y,0),
-            new THREE.Vector3(boxBound.max.x, boxBound.max.y,0),
-            new THREE.Vector3(boxBound.min.x, boxBound.max.y,0)
-        ]
-
-        var intersect = (pointcloud)=>{
-        
-            if(!pointcloud.bound.intersectsBox(boxBound))return false
-            //判断box和点云的tight bound是否相交(因为box可以任意旋转,且实在找不到三维中的立方体相交的函数,所以直接用boxBound) 
-            var points = pointcloud.getUnrotBoundPoint('all') 
-            let rings = math.getPolygonsMixedRings([points.slice(0,4), boxPoints] , true) 
-            //console.log(pointcloud.dataset_id, pointcloud.name, rings.length) 
-            if(rings.length > 1 )return false
-
-            {//再用frustum和数据集的sphere相交试试,能排除一些错误
-                let a = Potree.Utils.isInsideBox(points,  boxMatrixInverse) 
-                if(!a){
-                    console.log('没能经过isInsideBox测试')
-                }
-                return a
-            }
-            return true 
-            
-        }
-
-        
-
-
-        return viewer.scene.pointclouds.filter(e=>intersect(e)) 
-        
-       
-
-    }
-    
-    
-   
-    /* 
-    裁剪点云时,2D界面显示全部平面图,按楼层切换显示。 
-     */
-    
-}
-
-
-
-export {Clip} 

+ 0 - 391
src/modules/datasetAlignment/Alignment.js

@@ -1,391 +0,0 @@
-
-import * as THREE from "../../../libs/three.js/build/three.module.js";
-import SplitScreen4Views from "../../utils/SplitScreen4Views.js"
-import math from "../../utils/math.js"
-import History from "../../utils/History.js"
-import { EventDispatcher } from "../../EventDispatcher.js";
-
-var Alignment = {
-    SplitScreen: SplitScreen4Views, 
-    handleState:null,  //操作状态 'translate'|'rotate'
-    bus: new EventDispatcher(), 
-    
-    prepareRecord : true, 
-    
-    writeToHistory(content){ 
-        if(!this.prepareRecord)return;
-        this.prepareRecord = false
-        this.history.writeIn(content)
-    },
-    
-    
-    /* undo(){//撤销一步 
-        let last = this.history.pop();
-        last && last.forEach(item=>{
-            this.applyTemp(item)  
-        })
-        
-    },  */ 
-    
-    applyTemp(item){ 
-        var pointcloud = viewer.scene.pointclouds.find(p=>p.dataset_id+p.name == item.sid)
-            pointcloud.orientationUser = item.orientationUser
-            pointcloud.translateUser = item.translateUser
-            this.setMatrix( pointcloud )
-    },
-    getTemp(pointclouds){//记录最近一次保存后的状态,便于恢复
-        pointclouds = pointclouds || viewer.scene.pointclouds
-        return pointclouds.map(e=>{
-            return {
-                sid : e.dataset_id+e.name,
-                orientationUser : e.orientationUser,
-                translateUser : e.translateUser.clone(),
-            }
-        } )
-    },
-    
-    
-    
-    init:function(){ 
-        let rotateInfo   
-        
-        viewer.fpControls.addEventListener("transformPointcloud",(e)=>{ 
-            if(e.pointclouds[0].dataset_id == Potree.settings.originDatasetId){//禁止手动移动初始数据集
-                return this.bus.dispatchEvent('forbitMoveOriginDataset') 
-            }
-            
-            
-            this.writeToHistory(this.getTemp(e.pointclouds) ) 
-             
-            
-            
-            
-        
-            if(this.handleState == 'translate'){
-                e.pointclouds.forEach(cloud=>Alignment.translate(cloud, e.moveVec))
-                
-                
-            }else if(this.handleState == 'rotate'){
-                if(Potree.settings.editType == 'pano'){
-                    
-                    let center = e.intersectStart //旋转中心是mousedown的位置
-                    if(e.intersect.equals(center))return
-                    if(!rotateInfo){  
-                        rotateInfo = {
-                            orientationUser : e.pointclouds[0].orientationUser,
-                            //vecStart : e.moveVec, // 首次移动向量 只有八个方向,精度太小,所以延迟 
-                            pointclouds: e.pointclouds
-                        } 
-                        this.bus.dispatchEvent({type:'rotateStart', startPoint:center})
-                        return
-                    }else if(!rotateInfo.vecStart){  
-                        let vec = new THREE.Vector3().subVectors(e.intersect, center).setZ(0)
-                        if(vec.length() * e.camera.zoom >  30){  //在屏幕上距离初始点有一定距离后开始算
-                            //console.log('moveVec',vec)
-                            rotateInfo.vecStart = vec
-                        }
-                    }else{
-                        
-                        let vec = new THREE.Vector3().subVectors(e.intersect, center).setZ(0)
-                        let angle = math.getAngle(rotateInfo.vecStart,vec,'z')   
-                        let diffAngle = rotateInfo.orientationUser + angle - rotateInfo.pointclouds[0].orientationUser
-                        
-                        rotateInfo.pointclouds.forEach(cloud=>{
-                            
-                           /*  let centerNoTranfrom = Potree.Utils.datasetPosTransform({ toDataset: true, pointcloud:cloud, position: center }) //中心点在数据集中的位置
-                            Alignment.rotate(cloud, null, diffAngle)
-                             
-                            let centerNow = Potree.Utils.datasetPosTransform({ fromDataset: true, pointcloud:cloud, position: centerNoTranfrom }) //中心点的现在位置
-                            let shift = new THREE.Vector3().subVectors( center, centerNow); //偏移量
-                            Alignment.translate(cloud,shift)   //使center还保留在原位
-                            //let centerNow1 = Potree.Utils.datasetPosTransform({ fromDataset: true, pointcloud:rotateInfo.pointcloud, position: centerNoTranfrom }) //中心点的现在位置
-                                 */
-                                 
-                            Alignment.rotateAround(center, cloud, null, diffAngle)   
-                                
-                                 
-                        })
-                        
-                        
-                    }
-                    this.bus.dispatchEvent({type:'rotate', endPoint: e.intersect})
-                    
-                }else{ 
-                    let center = e.pointclouds[0].translateUser //移动到的位置就是中心
-                    if(e.intersect.equals(center))return
-                    if(!rotateInfo){  
-                        rotateInfo = {
-                            orientationUser : e.pointclouds[0].orientationUser,
-                            vecStart : new THREE.Vector3().subVectors(e.intersectStart, center).setZ(0),
-                            //pointclouds: e.pointclouds
-                            pointcloud: e.pointclouds[0]
-                        }  
-                    }else{ 
-                        let vec = new THREE.Vector3().subVectors(e.intersect, center).setZ(0)
-                        let angle = math.getAngle(rotateInfo.vecStart,vec,'z')   
-                        let diffAngle = rotateInfo.orientationUser + angle - rotateInfo.pointcloud.orientationUser
-                        Alignment.rotate(rotateInfo.pointcloud, null, diffAngle)
-                    }
-                }    
-            } 
-        })
-        
-        
-        viewer.fpControls.addEventListener("end",(e)=>{ 
-            rotateInfo = null 
-            this.prepareRecord = true
-        })
-        
-        viewer.inputHandler.addEventListener('keydown',e=>{ 
-            if(e.keyCode == 90 && e.event.ctrlKey){//Z
-                this.history.undo()
-            } 
-        })  
-		 
-        
-        // cursor:
-        
-        let updateCursor = (e)=>{ 
-            if(e.drag || !this.editing)return  //仅在鼠标不按下时更新:
-            
-            let handleState = Alignment.handleState
-            
-            if(e.hoverViewport.alignment && handleState && e.hoverViewport.alignment[handleState]){
-                if(handleState == 'translate'){
-                    if( e.intersect && e.intersect.location ){ 
-                        viewer.dispatchEvent({
-                            type : "CursorChange", action : "add",  name:"movePointcloud"
-                        })
-                    }else{
-                        viewer.dispatchEvent({
-                            type : "CursorChange", action : "remove",  name:"movePointcloud"
-                        })
-                    }
-                }else if(handleState == 'rotate'){ 
-                    if( e.intersect && e.intersect.location ){ 
-                        viewer.dispatchEvent({
-                            type : "CursorChange", action : "add",  name:"rotatePointcloud"
-                        })
-                    }else{
-                        viewer.dispatchEvent({
-                            type : "CursorChange", action : "remove",  name:"rotatePointcloud"
-                        })
-                    }
-                }  
-            }else{
-                //清空:
-                viewer.dispatchEvent({
-                    type : "CursorChange", action : "remove",  name:"movePointcloud" 
-                })
-                viewer.dispatchEvent({
-                    type : "CursorChange", action : "remove",  name:"rotatePointcloud" 
-                })
-            }                
-        }
-        
-         
-        viewer.addEventListener('global_mousemove',updateCursor)  
-        viewer.addEventListener('global_drop',updateCursor)//拖拽结束  
-       
-            
-        
-        
-        viewer.addEventListener('updateModelBound', (e)=>{
-            if(this.editing){
-                this.SplitScreen.updateCameraOutOfModel() 
-            } 
-        })
-        
-        
-    },
-    
-    
-    setMatrix :  function(pointcloud){
-        var vec1 = pointcloud.position     //position为数据集内部的偏移,在navvis中对应的是dataset.pointCloudSceneNode的children[0].position
-        var vec2 = pointcloud.translateUser
-        var angle = pointcloud.orientationUser
-        var pos1Matrix = new THREE.Matrix4().setPosition(vec1);//先移动到点云本身应该在的初始位置(在4dkk里和其他应用中都是在这个位置的,也能和漫游点对应上)
-        var rotMatrix = new THREE.Matrix4().makeRotationAxis(new THREE.Vector3(0,0,1), angle)//再旋转 
-        var pos2Matrix = new THREE.Matrix4().setPosition(vec2);//最后是平移
-         
-        var matrix = new THREE.Matrix4().multiplyMatrices(pos2Matrix, rotMatrix);
-        pointcloud.transformMatrix = matrix.clone();//为该数据集的变化矩阵。 对应navvis的m2w_
-        pointcloud.transformInvMatrix.copy(matrix).invert()
-        pointcloud.rotateMatrix = rotMatrix
-        pointcloud.rotateInvMatrix.copy(rotMatrix).invert()
-        
-        
-        pointcloud.panos.forEach(e=>e.transformByPointcloud())
-        
-        
-        matrix = new THREE.Matrix4().multiplyMatrices(matrix, pos1Matrix);
-        
-        
-        
-        pointcloud.matrix = matrix;
-        //pointcloud.matrixWorldNeedsUpdate = true //更新matrixWorld (非计算,直接赋值)
-        pointcloud.updateMatrixWorld(true)
-        
-        if(this.editing){
-            Alignment.changeCallBack && Alignment.changeCallBack();
-        } 
-        
-        if(pointcloud.spriteNodeRoot){
-            pointcloud.spriteNodeRoot.matrixWorld.copy(pointcloud.matrixWorld)//.multiplyMatrices(pointcloud.matrixWorld, pointcloud.matrixWorld);	
-        } 
-
-        viewer.updateModelBound();
-        //pointcloud.updateBound()
-        pointcloud.getPanosBound()  
-        
-
-    },
-    
-    
-    rotateAround(center, pointcloud, deg, angle){//绕center点转动
-        var angle = angle != void 0 ? angle : THREE.Math.degToRad(deg) 
-        let vec1 = new THREE.Vector3().subVectors(pointcloud.translateUser, center);
-        let rotMatrix = new THREE.Matrix4().makeRotationAxis(new THREE.Vector3(0,0,1), angle)
-        let vec2 = vec1.clone().applyMatrix4(rotMatrix) //将到旋转中心的偏差也转动
-        let vec3 = new THREE.Vector3().subVectors(vec2,vec1); //这个就是多出来的一步translateUser
-        this.rotate(pointcloud, deg, angle) 
-        this.translate(pointcloud, vec3)
-        //绕点转动就是比普通转动多一步移动到相对center的某个位置。 1 初始点云移动到自己的position; 2 移动一个vec1  3绕原点旋转 4再移动一个原本的translateUser。 绘制出来后发现移动量就是第二步vec旋转后的偏移
-    },
-    
-    
-    rotate:function(pointcloud, deg, angle){//绕各自中心转动(各自的position)   假设点云位移position后0,0,0就是它的中心了(根据navvis观察这样做是绕同一个点旋转的)
-        var angle = angle != void 0 ? angle : THREE.Math.degToRad(deg)   //正逆负顺
-        pointcloud.orientationUser += angle
-        Alignment.setMatrix(pointcloud)
-    },
-    translate:function(pointcloud, vec){
-        pointcloud.translateUser.add(vec)
-        Alignment.setMatrix(pointcloud)
-    },
-    
-    
-    
-    
-    enter:function(){
-        //this.saveTemp()  
-        this.originData = this.getTemp() 
-        
-        this.SplitScreen.split({alignment:true})
-         
-        viewer.images360.panos.forEach(pano=>{
-            viewer.updateVisible(pano.mapMarker, 'split4Screens', false)
-        }) 
-        
-        viewer.viewports.find(e=>e.name == 'mapViewport').alignment = {rotate:true,translate:true};
-        viewer.viewports.find(e=>e.name == 'right').alignment = {translate:true};
-        viewer.viewports.find(e=>e.name == 'back').alignment = {translate:true};
-        
-        
-        this.editing = true
-        
-        viewer.updateFpVisiDatasets()
-        
-        
-        
-    },
-    leave:function(){
-        this.switchHandle(null)
-        
-        /* this.originData.forEach(e=>{//恢复
-            var pointcloud = viewer.scene.pointclouds.find(p=>p.dataset_id == e.id)
-            this.translate(pointcloud, new THREE.Vector3().subVectors(e.translateUser , pointcloud.translateUser))
-            this.rotate(pointcloud, null, e.orientationUser - pointcloud.orientationUser)
-        }) */
-        this.originData.forEach(e=>{//恢复
-            this.applyTemp(e)
-        })
-        
-        
-        this.SplitScreen.recover()
-        viewer.images360.panos.forEach(pano=>{
-            viewer.updateVisible(pano.mapMarker, 'split4Screens', true)
-        }) 
-        this.editing = false
-        this.history.clear() 
-        viewer.updateFpVisiDatasets()
-        viewer.dispatchEvent({
-            type : "CursorChange", action : "remove",  name:"movePointcloud" 
-        })
-        viewer.dispatchEvent({
-            type : "CursorChange", action : "remove",  name:"rotatePointcloud" 
-        })
-    } 
-    
-    ,
-    switchHandle:function(state){
-        this.handleState = state
-        //清空:
-        viewer.dispatchEvent({
-            type : "CursorChange", action : "remove",  name:"movePointcloud" 
-        })
-        viewer.dispatchEvent({
-            type : "CursorChange", action : "remove",  name:"rotatePointcloud" 
-        })
-        
-        this.bus.dispatchEvent({type:'switchHandle' , state })
-        
-        
-
-    },
-    
-    
-    save: function(){//保存所有数据集的位置和旋转
-        let callback = ()=>{//保存成功后
-            this.originData = this.getTemp()   //this.saveTemp();
-            //需要修改 测量线的position。漫游点已经实时修改了
-            
-            viewer.scene.measurements.forEach(e=>e.transformByPointcloud())
-            viewer.images360.updateCube(viewer.bound)
-        }
-        
-        var data = viewer.scene.pointclouds.map(e=>{
-            let pos = viewer.transform.lonlatToLocal.inverse(e.translateUser.clone())
-            
-            
-            return {
-                id: e.dataset_id,
-                orientation : e.orientationUser,
-                location:[pos.x, pos.y, pos.z],
-                //transformMatrix: e.transformMatrix.elements,
-            }
-        })
-        //data = JSON.stringify(data)
-        
-        //test: 退出后保留结果
-        if(!Potree.settings.isOfficial){
-            callback() 
-        }
-        
-        return {data, callback}
-    }
-        
-    
-}
-
-
-Alignment.history = new History({ 
-    callback: (data)=>{ 
-        data.forEach(item=>{
-            Alignment.applyTemp(item)  
-        }) 
-    } 
-})
-
-/* 
-
-关于控制点:
-
-两个控制点只能打在同一个数据集上。传输这两个点的4dkk中的本地坐标和经纬度,后台算出该数据集的旋转平移,
-然后其他数据集绕该数据集旋转,并保持相对位置不变。
-
-
- */
- 
-
-export {Alignment} 

+ 0 - 616
src/modules/mergeModel/MergeEditor.js

@@ -1,616 +0,0 @@
- 
-import * as THREE from "../../../libs/three.js/build/three.module.js";
-import cameraLight from '../../utils/cameraLight.js' 
-
-import math from "../../utils/math.js"
-import Common from '../../utils/Common.js' 
-import {LineDraw, MeshDraw} from "../../utils/DrawUtil.js"; 
-import {transitions, easing, lerp} from '../../utils/transitions.js'
-import SplitScreen from "../../utils/SplitScreen.js";
-import InfiniteGridHelper from '../../objects/InfiniteGridHelper.js'
-import Compass from "../../objects/tool/Compass.js";
-import {TransformControls} from "../../objects/tool/TransformControls.js";
-import History from "../../utils/History.js"
-import {ExtendEventDispatcher} from "../../custom/ExtendEventDispatcher.js";
-
-const texLoader = new THREE.TextureLoader() 
-      texLoader.crossOrigin = "anonymous" 
-  
-const edgeStrengths = {
-    pointcloud: 4,
-    glb: 100
-}
-const viewportProps = [{
-    left:0,
-    bottom:0,
-    width: 0.5,height:1,
-    name : 'top',    
-    axis:["x","y"],
-    direction : new THREE.Vector3(0,0,-1), //镜头朝向 
-    active: true,
-    //相机位置在z轴正向
-    limitBound: new THREE.Box3(new THREE.Vector3(-Infinity,-Infinity, 1),new THREE.Vector3(Infinity,Infinity,5000)), //在地面以上
-    margin:{x:50, y:150} ,
-},
-{
-    left:0.5,
-    bottom:0,
-    width: 0.5,height:1,
-    name : 'right', 
-    axis:["y","z"],
-    direction : new THREE.Vector3(1,0,0), 
-    active: true,
-    //相机位置在x轴负向  右下角屏
-    viewContainsPoints:[new THREE.Vector3(0,0,0)],
-    margin:{x:300, y:250} ,
-} ]
- 
- 
- 
-let MergeEditor = {
-    bus:new ExtendEventDispatcher(), 
-     
-    
-    SplitScreen : new SplitScreen(),
-    
-    init(){  
-        { 
-            let ground = this.ground = new InfiniteGridHelper(1, 10000, new THREE.Color('#fff'), 10000, 0.2, 0.3)
-            viewer.scene.scene.add(ground) 
-            //再加两条线否则在正侧边看不到
-            let line1 = LineDraw.createLine([new THREE.Vector3(-10000, 0, 0),new THREE.Vector3(10000, 0, 0) ], {color:'#666', dontAlwaysSeen:true})
-            let line2 = LineDraw.createLine([new THREE.Vector3(0, -10000, 0),new THREE.Vector3(0, 10000, 0) ], {mat:line1.material})
-            ground.renderOrder = Potree.config.renderOrders.model + 1//line1.renderOrder + 1  //要比模型低,否则模型透明时效果不对
-            ground.add(line1)
-            ground.add(line2)
-             
-            ground.material.polygonOffset = true //多边形偏移(视觉上没有移动模型位置),防止闪烁
-            ground.material.polygonOffsetFactor = 100 //多边形偏移因子
-			ground.material.polygonOffsetUnits = 10 //多边形偏移单位  
-            ground.material.depthWrite = false            
-            //ground.material.depthTest = false
-            line1.material.polygonOffset = true
-            line1.material.polygonOffsetFactor = 130  
-			line1.material.polygonOffsetUnits = 10  
-            line1.material.depthWrite = false   
-            //见笔记:透明物体的材质设置
-        }
-        
-        
-        {
-            
-            this.transformControls = new TransformControls(viewer.mainViewport.camera, viewer.renderArea,{
-                dontHideWhenFaceCamera: true,
-            });
-            //this.transformControls.space = 'local'//为了在当前方向上平移
-            this.transformControls.setSize(1.5)
-            viewer.scene.scene.add(this.transformControls)
-            
-            //右屏
-            this.transformControls2 = new TransformControls(viewer.mainViewport.camera, viewer.renderArea,{ 
-                dontHideWhenFaceCamera: true,
-            }); 
-            this.transformControls.setSize(1.5)
-            viewer.scene.scene.add(this.transformControls2) 
-            viewer.setObjectLayers(this.transformControls2, 'layer2' )  
-            
-            let mouseDown = (e)=>{
-                 
-                viewer.outlinePass.edgeStrength = 0//暂时消失线
-                 
-            }
-            let mouseUp = (e)=>{
-                 
-                this.updateEdgeStrength()
-                 
-            }
-            this.transformControls.addEventListener('mouseDown',mouseDown)
-            this.transformControls2.addEventListener('mouseDown',mouseDown)
-            this.transformControls.addEventListener('mouseUp',mouseUp)
-            this.transformControls2.addEventListener('mouseUp',mouseUp)
-            
-            
-        }
-        
-        
-        {
-            
-            this.secondCompass = new Compass(null)
-            
-        }
-        
-        viewer.setControls(viewer.orbitControls)
-        //viewer.mainViewport.view.fixZWhenPan = true
-        viewer.orbitControls.constantlyForward = true
-        
-        
-        viewer.addEventListener('global_single_click',(e)=>{
-            if(
-                this.noNeedSelection  //如模型查看页
-                || viewer.scene.cameraAnimations.some(c=>c.onUpdate) //正在播放
-                || e.drag && e.drag.notPressMouse   //在加测量线
-                || viewer.mainViewport.view.isFlying() //有其他校准
-                || this.split           //分屏中
-                || e.clickElement //触发别的点击事件,如测量时click marker  /* && e.clickElement != e.intersect.object */
-            ){
-                return
-            }
-            
-            if(e.intersect){
-                let object = e.intersect.object || e.intersect.pointcloud
-                let objects = this.getAllObjects()
-                if(objects.includes(object)){ 
-                    this.selectModel(object) 
-                }else{
-                    //if(!viewer.inputHandler.selection[0]){//正在平移和旋转,不允许取消
-                        this.selectModel(null)
-                    //}
-                }                    
-            }else{
-                //if(!viewer.inputHandler.selection[0]){
-                    this.selectModel(null)
-                //}                
-            }
-        })  
-        
-        viewer.inputHandler.addEventListener('keydown', (e)=>{
-            if((e.event.key).toLowerCase() == "h" ){ 
-                this.fadeOutlineAuto = !this.fadeOutlineAuto
-                this.showModelOutline(this.selected,!!this.selected)
-            } 
-        })
-        viewer.ssaaRenderPass.enabled = false
-        viewer.outlinePass.enabled = true
-        //Potree.settings.intersectWhenHover = false
-        //viewer.updateVisible(viewer.reticule, 'force', false)
-        
-        viewer.mainViewport.camera.near = 0.05; // too small will result in z-fighting
-        
-        viewer.addEventListener('updateModelBound', (e)=>{
-            if(this.split){ 
-                this.SplitScreen.updateCameraOutOfModel(/* this.selected && [this.selected] */) 
-            } 
-        })
-        
-        
-        {//校准页面拖拽
-            //左右屏都可以拖拽模型,旋转只能左屏
-            let dragInfo  
-            let drag = (e)=>{ 
-                if(this.split &&  this.selected && this.transformState && (e.dragViewport.name == 'top' || this.transformState == 'translate')   ){ 
-                    if(e.type == 'global_mousedown' ){ //开始
-                        //if((e.intersect.object || e.intersect.pointcloud) == this.selected){
-                        if(e.intersect.pointclouds.includes(this.selected) || e.intersect.allElements.some(e=>e.object == this.selected)){
-                            
-                            dragInfo = {}   
-                            //if(this.selected.isPointcloud){ 
-                                viewer.outlinePass.edgeStrength = 0//暂时消失线
-                            //} 
-                        }  
-                    }
-                         
-                    if(e.type == 'global_drag' && dragInfo  ){ 
-                        if(this.transformState == 'translate'){ 
-                        
-                            let moveVec = Potree.Utils.getOrthoCameraMoveVec(e.drag.pointerDelta, e.dragViewport.camera )//最近一次移动向量
-                            this.selected.position.add(moveVec)
-                            
-                            this.selected.dispatchEvent("position_changed")
-                        }else if(this.transformState == 'rotate'){
-                            
-                            let vec = new THREE.Vector3().subVectors(e.intersect.orthoIntersect || e.intersect.location, this.selected.boundCenter).setZ(0)
-                            if(dragInfo.lastVec == void 0){//global_mousedown
-                                dragInfo.lastVec = vec 
-                                return
-                            }
-                            let angle = math.getAngle(dragInfo.lastVec, vec, 'z')   
-                            dragInfo.lastVec = vec
-                            
-                            //this.selected.rotation.z += angle //局部
-                            
-                            
-                            /* object.quaternion.copy( .setFromAxisAngle( new THREE.Vector3(0,0,1), angle ) );
-                            object.quaternion.multiply( quaternionStart ).normalize(); */
-                            let diffQua = new THREE.Quaternion().setFromAxisAngle( new THREE.Vector3(0,0,1), angle )
-                            this.selected.quaternion.premultiply(diffQua) //世界
-                            
-                            
-                            this.selected.dispatchEvent("rotation_changed")
-                        }
-                        
-                        return {stopContinue:true}
-                    } 
-                }
-                
-            }
-            
-            viewer.addEventListener('global_mousedown',  drag) 
-            viewer.addEventListener('global_drag', drag, 10)
-            viewer.addEventListener('global_mousemove', (e)=>{
-                if(this.split && this.transformState && !e.drag && (e.hoverViewport.name == 'top' ||  this.transformState == 'translate')){
-                    
-                    /* if(this.lastHoverViewport != e.hoverViewport){
-                        this.lastHoverViewport = e.hoverViewport
-                        this.transformControls.view = e.hoverViewport.view
-                        this.transformControls.camera = e.hoverViewport.camera
-                        this.transformControls.hideAxis( this.transformState, e.hoverViewport.name == 'top' ? [z] : [x,y]);
-                    } */
-                    
-                    
-                    
-                    
-                    let mouseover =  e.intersect.pointclouds.includes(this.selected) || e.intersect.allElements.some(e=>e.object == this.selected)
-                    //let mouseover = (e.intersect.object || e.intersect.pointcloud) == this.selected
-                    if(mouseover){
-                        if(this.transformState == 'translate'){
-                            viewer.dispatchEvent({
-                                type : "CursorChange", action : "add",  name:"movePointcloud" 
-                            }) 
-                        }else{
-                            viewer.dispatchEvent({
-                                type : "CursorChange", action : "add",  name:"rotatePointcloud" 
-                            }) 
-                        }
-                    }else{
-                        this.clearTranCursor()
-                    }
-                    
-                } 
-            })
-            
-            viewer.addEventListener('global_drop', (e)=>{
-                dragInfo = null
-                this.clearTranCursor()
-                  
-                this.updateEdgeStrength()
-                  
-                
-            })
-        
-        }
-    },
-    
-    
-    clearTranCursor(){
-        viewer.dispatchEvent({
-            type : "CursorChange", action : "remove",  name:"movePointcloud" 
-        })
-        viewer.dispatchEvent({
-            type : "CursorChange", action : "remove",  name:"rotatePointcloud" 
-        })
-    },
-    
-    enterSplit(){ 
-        this.split = true
-        if(this.selected) this.SplitScreen.focusCenter = this.selected.boundCenter //旋转中心。注意 boundCenter不能直接赋值,否则改变后focusCenter也要改
-        else this.SplitScreen.focusCenter = null
-        
-        this.SplitScreen.splitStart(viewportProps)
-        
-        this.beforeSplit = {
-            pointDensity: Potree.settings.pointDensity,
-        }
-        Potree.settings.pointDensity = 'fourViewports' //强制降低点云质量
-        /* viewer.scene.pointclouds.forEach(e=>{
-            e.material.activeAttributeName = "color"
-            e.material.useFilterByNormal = true  
-        }) */ 
-        //取消outline,改点云颜色为和outline一样的颜色
-        /* if(this.selected && this.selected.isPointcloud){ 
-            this.showModelOutline(this.selected, false) 
-            this.selected.material.activeAttributeName = "color"
-            this.selected.material.color = viewer.outlinePass.visibleEdgeColor 
-        } */
-        
-        
-        viewer.setControls(viewer.fpControls)  
-        viewer.viewports.find(e=>e.name == 'right').rotateSide = true 
-        viewer.viewports.find(e=>e.name == 'top').alignment = true
-       
-         
-        viewer.viewports[1].layersAdd('layer2') 
-        viewer.viewports[0].layersAdd('layer1') 
-        viewer.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'] }
-        this.transformControls2.view = viewer.viewports[1].view
-        this.transformControls2.camera = viewer.viewports[1].camera
-        this.transformControls2._gizmo.hideAxis = {translate:['x','y'], rotate:['x','y','z'] }
-        
-
-        this.secondCompass.changeViewport(viewer.viewports[0])
-        this.secondCompass.setDomPos()
-        this.secondCompass.setDisplay(true)   
-        viewer.compass.changeViewport(viewer.viewports[1])
-        viewer.compass.setDomPos()
-        
-    },
-    
-    leaveSplit(){
-        this.split = false
-        this.SplitScreen.unSplit()    
-        viewer.setControls(viewer.orbitControls)
-        
-        Potree.settings.pointDensity = this.beforeSplit.pointDensity
-        /* if(this.selected && this.selected.isPointcloud){ 
-            this.showModelOutline(this.selected, true) 
-            this.selected.material.activeAttributeName = "rgba"  
-        } */
-        this.transformControls.camera = viewer.viewports[0].camera
-        this.transformControls.view = viewer.viewports[0].view 
-        this.transformControls._gizmo.hideAxis = {}
-        viewer.setObjectLayers(this.transformControls, 'sceneObjects' )  //恢复
-        
-        
-        viewer.compass.changeViewport(viewer.viewports[0]) //恢复 
-        viewer.compass.setDomPos()
-        this.secondCompass.setDisplay(false)
-        
-         
-    },
-    
-    rotateSideCamera(angle){
-        this.SplitScreen.rotateSideCamera(viewer.viewports.find(e=>e.name == 'right'), angle)
-    },
-    
-    setTransformState(state){//校准时
-        this.transformState = state  
-        this.clearTranCursor()       
-    },
-    //---------------------------
-    
-    /* writeToHistory(content){ 
-        if(!this.prepareRecord)return;
-        this.prepareRecord = false
-        this.history.push(content)
-    }, */
-    
-    //---------------------------
-    
-    getAllObjects(){
-        return viewer.objs.children.concat(viewer.scene.pointclouds)
-    },
-    
-    getModel(id){
-        let models = this.getAllObjects()
-        return models.find(e=>e.dataset_id == id)
-    },
-    removeModel(model){
-        if(this.selected == model) this.selectModel(null)
-        let dispose = (e)=>{
-            e.geometry && e.geometry.dispose() 
-            e.material && e.material.dispose()
-        }
-        if(model.isPointcloud){
-            dispose(model)
-            viewer.scene.removePointCloud(model)
-        }else{
-            model.traverse(e=>{
-                dispose(e) 
-            })
-            viewer.objs.remove(model)
-        }   
-        
-        
-        
-    },
-    
-    selectModel(model, state=true, fitBound, by2d){
-        if(!model) {
-            model = this.selected
-            state = false
-        }
-         
-        if(state){
-            if(this.selected){
-                if(this.selected == model) return
-                else{
-                    let transToolAttached = !!this.transformControls.object
-                    this.selectModel(this.selected, false, fitBound, by2d)
-                    transToolAttached && this.transformControls.attach(model)
-                }
-            }
-            this.selected = model
-             
-            MergeEditor.focusOn(model, 500, !!fitBound)     //通过在场景里点击模型的话,不focus
-              
-           
-            this.showModelOutline(model)
-            
-            
-            
-            this.updateEdgeStrength()
-            
-            //console.log('selectModel', model)
-            
-        }else{
-            if(this.selected != model)return //model本来就没选中,不需要处理(防止2d先选中新的再取消旧的)
-            this.showModelOutline(model, false)
-             
-            this.selected = null
-            this.transformControls.detach()        //viewer.transformObject(null);
-            //console.log('selectModel', null)
-        } 
-        
-        
-        
-        if(!by2d && model){
-            model.dispatchEvent({type:'changeSelect', selected : state})
-        }
-         
-    },
-    
-    
-    showModelOutline(model, state){ 
-        if(this.fadeOutlineAuto){ 
-            if(state === false){
-                viewer.outlinePass.selectedObjects = []
-                clearTimeout(this.timer)
-                return
-            }
-            
-            viewer.outlinePass.selectedObjects = [model]
-            if(this.timer){
-                clearTimeout(this.timer)
-            }
-            
-            this.timer = setTimeout(()=>{
-                viewer.outlinePass.selectedObjects = []
-            }, 1000)
-        }else{
-            if(state === false){
-                viewer.outlinePass.selectedObjects = []
-            }else{
-                viewer.outlinePass.selectedObjects = [model]
-            }
-        }
-    },
-    
-    updateEdgeStrength(){
-        if(!this.selected)return
-        if(this.selected.isPointcloud){
-            viewer.outlinePass.edgeStrength = edgeStrengths.pointcloud// / this.selected.material.opacity  
-        }else{
-            viewer.outlinePass.edgeStrength = edgeStrengths.glb
-        }  
-    },
-    focusOn(objects, duration = 400, fitBound=true, dontLookUp){  
-        if(!(objects instanceof Array)){
-            objects = [objects]
-        }
-        let boundingBox = new THREE.Box3
-        objects.forEach(object=>{
-            boundingBox.union(object.boundingBox.clone().applyMatrix4(object.matrixWorld))
-        })
-         
-        if(fitBound){
-            viewer.focusOnObject({boundingBox}, 'boundingBox', duration, {dontLookUp, dontChangeCamDir:true}) 
-        }else{ 
-        
-            /* 
-            let position = viewer.inputHandler.intersect ? viewer.inputHandler.intersect.location : boundingBox.getCenter(new THREE.Vector3)
-            position && viewer.focusOnObject({position},  'point', duration, {dontChangePos: true})
-             */
-            let position = viewer.inputHandler.intersect ? viewer.inputHandler.intersect.location : boundingBox.getCenter(new THREE.Vector3)
-            if(!position)return
-            
-            
-            /* let targetOld = viewer.mainViewport.view.getPivot()
-            
-            let projected1 = targetOld.clone().project(viewer.mainViewport.camera);
-            let projected2 = position.clone().project(viewer.mainViewport.camera); //使用其z
-			let targetNew = projected1.clone().setZ(projected2.z).unproject(viewer.mainViewport.camera); 
-            viewer.mainViewport.view.lookAt(targetNew) */
-            
-            
-            viewer.mainViewport.view.radius = viewer.mainViewport.camera.position.distanceTo(position)
-            //为了不改画面,不调节方向了,只能调调radius,一定程度将target靠近model
-        }  
-    },
-    
-    
-    moveBoundCenterTo(model,pos){ //使boundCenter在所要的位置 
-        let diff = new THREE.Vector3().subVectors(pos, model.boundCenter) 
-        model.position.add(diff); 
-    },
-    
-    getBoundCenter(model){
-        if(!model.boundCenter) model.boundCenter = new THREE.Vector3
-        model.boundingBox.getCenter(model.boundCenter).applyMatrix4(model.matrixWorld) 
-    },
-    
-    setModelBtmHeight(model, z ){  
-        //无论模型怎么缩放、旋转,都使最低点为z
-        if(z == void 0) z = model.btmHeight; //维持离地高度
-        else model.btmHeight = z;
-        
-        model.updateMatrixWorld()
-        let boundingBox2 = model.boundingBox.clone().applyMatrix4(model.matrixWorld)
-        let size = boundingBox2.getSize(new THREE.Vector3);
-        let center = boundingBox2.getCenter(new THREE.Vector3);
-        let hopeZ = z + size.z / 2  
-        //model.position.z = z + size.z / 2 - center.z 
-        model.position.z += (hopeZ - center.z)
-    },
-    
-    computeBtmHeight(model){ //位移之后重新计算btmHeight
-        model.updateMatrixWorld()
-        let boundingBox2 = model.boundingBox.clone().applyMatrix4(model.matrixWorld)
-        let size = boundingBox2.getSize(new THREE.Vector3);
-        let center = boundingBox2.getCenter(new THREE.Vector3);
-        model.btmHeight = center.z - size.z / 2 
-    },
-    
-    
-    maintainBoundXY(model){ //在旋转和缩放后,立即执行这个函数,使boundCenter保持原位
-         
-        model.updateMatrixWorld()
-        let center1 = model.boundCenter.clone();//还未更新的 
-        this.getBoundCenter(model)//更新
-        let center2 = model.boundCenter.clone();
-        let diff = new THREE.Vector2().subVectors(center1,center2); 
-        model.position.x += diff.x;
-        model.position.y += diff.y;
-        model.boundCenter.copy(center1)
-    }, 
-     
-    
-    
-    maintainBoundCenter(model){
-        model.updateMatrixWorld()
-        let center1 = model.boundCenter.clone();//还未更新的 
-        this.getBoundCenter(model)//更新
-        let center2 = model.boundCenter.clone();
-        let diff = new THREE.Vector3().subVectors(center1,center2); 
-        model.position.add(diff)
-        model.boundCenter.copy(center1)
-    },
-    
-    modelTransformCallback(model){
-        
-        model.updateMatrixWorld() 
-        if(model.matrixWorld.equals(model.lastMatrixWorld))return
-        viewer.scene.measurements.forEach(measure=>{
-            let changed
-            measure.points_datasets.forEach((dataset_id,i)=>{
-                if(dataset_id == model.dataset_id){
-                    changed = true
-                    measure.points[i] = Potree.Utils.datasetPosTransform({fromDataset:true,datasetId:dataset_id, position:measure.dataset_points[i].clone()})
-                    measure.updateMarker(measure.markers[i], measure.points[i])
-                   
-                }
-            })
-            if(changed){//仿transformByPointcloud
-                measure.getPoint2dInfo(measure.points)
-                measure.update() 
-                measure.setSelected(false)//隐藏edgelabel  
-            }
-        })
-        
-          
-     
-        
-        model.lastMatrixWorld = model.matrixWorld.clone()
-    }
-}   
-    
-    
-    
- 
-    
-    
-export default MergeEditor  
-    
-    
-/*  
-
-note:
-
-要注意getHoveredElements只在getIntersect时才使interactables包含加载的model, 也就是model上不能有使之成为interactables的事件,否则在鼠标hover到模型上开始转动的一瞬间很卡。
-
-
-
-
-
-*/ 

File diff suppressed because it is too large
+ 0 - 1227
src/modules/panoEdit/panoEditor.js


+ 0 - 653
src/modules/route/RouteGuider.js

@@ -1,653 +0,0 @@
-
-import * as THREE from "../../../libs/three.js/build/three.module.js";
-import {Utils} from "../../utils.js"; 
-import Sprite from '../../objects/Sprite.js'
-import Common from "../../utils/Common.js";
-import browser from '../../utils/browser.js'
-import {ExtendEventDispatcher} from "../../custom/ExtendEventDispatcher.js";
-
-const texLoader = new THREE.TextureLoader()
-const arrowSpacing = 1 //间隔
-const arrowSize = arrowSpacing * 0.5
-const planeGeo = new THREE.PlaneBufferGeometry(1,1);
-
-const sphereSizeInfo = {
-      nearBound : 2, scale:arrowSize, restricMeshScale : true,
-}
-//const arrowsShowingCount = 25; //场景里最多展示多少个箭头
-const arrowShowMinDis = 10
-export class RouteGuider extends ExtendEventDispatcher{
-    constructor () {
-		super();
-        
-        this.route = [];
-        this.curve = []
-        this.scenePoints = []
-        this.sceneMeshGroup = new THREE.Object3D;
-        this.mapMeshGroup = new THREE.Object3D;
-        this.generateDeferred;
-        viewer.addEventListener('loadPointCloudDone',this.init.bind(this))
-        
-        this.lastResult;//保存上一个的结果,以便于反向
-        this.datasetIds = [];//起始和终点的datasetId
-    }
-    init(){
-        if(this.inited) return;
-        
-        let zoom;
-        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){ 
-                    //console.log('updateMapArrows')
-                    this.updateMapArrows(true)
-                    zoom = camera.zoom         
-                    return true 
-                } 
-            }, browser.isMobile()?500:200)
-        })
-        
-   
-        
-       
-        //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
-             
-                //if(!currPos.equals(lastPos)){
-                   // lastPos.copy(currPos)
-                    this.updateArrowDisplay() 
-                     
-                    return true 
-                //}
-            }, 1000)
-            
-            
-                        
-        })
-        
-        
-        
-        var polesMats = {
-            shadowMat: new THREE.MeshBasicMaterial({ 
-                transparent:true, depthTest:false,
-                map: texLoader.load(Potree.resourcePath+'/textures/pano_instruction_bottomMarker.png' )  
-            }),
-            sphereMat : new THREE.MeshBasicMaterial({
-                transparent:true, depthTest:false,
-                map: texLoader.load(Potree.resourcePath+'/textures/whiteCircle.png' )  
-            }), 
-            hatMats:{
-                start:  new THREE.MeshBasicMaterial({
-                    transparent:true, depthTest:false,
-                    map: texLoader.load(Potree.resourcePath+'/textures/pano_instruction_start_route.png' )  
-                }),
-                end:  new THREE.MeshBasicMaterial({
-                    transparent:true, depthTest:false,
-                    map: texLoader.load(Potree.resourcePath+'/textures/pano_instruction_target_reached.png' )  
-                }) 
-            }
-        }
-        polesMats.shadowMat.map.anisotropy = 4 
-        
-        this.poleStart = this.createPole(polesMats, 'start') 
-        this.poleEnd = this.createPole(polesMats, 'end') 
-        
-        this.sceneMeshGroup.add(this.poleStart)
-        this.sceneMeshGroup.add(this.poleEnd)
-        
-        
-        let map = texLoader.load(Potree.resourcePath+'/textures/routePoint_panorama.png' )  
-        map.anisotropy = 4 // 各向异性过滤 .防止倾斜模糊 
-        this.arrow = new THREE.Mesh(planeGeo, new THREE.MeshBasicMaterial({
-            transparent:true,
-            depthTest:false, 
-            map
-        }))
-        this.arrow.scale.set(arrowSize,arrowSize,arrowSize)
-        viewer.setObjectLayers(this.arrow, 'sceneObjects' )
-         
-        
-        /* this.testArrow = this.arrow.clone();
-        this.testArrow.material = this.arrow.material.clone()
-        this.testArrow.material.color = 'red' */
-        
-        this.arrows = new THREE.Object3D;
-        this.sceneMeshGroup.add(this.arrows)
-        
-        viewer.setObjectLayers(this.sceneMeshGroup, 'sceneObjects' )
-        //this.sceneMeshGroup.traverse(e=>e.renderOrder = 90)
-        
-        
-        viewer.scene.scene.add(this.sceneMeshGroup);
-        this.sceneMeshGroup.visible = /* this.poleStart.visibile = this.poleEnd.visibile = */ false
-       
-        //-------------map---------------------
-        
-        /* this.mapMarkStart = new THREE.Mesh( planeGeo, new THREE.MeshBasicMaterial({
-            transparent:true, depthTest:false,
-            map: texLoader.load(Potree.resourcePath+'/textures/map_instruction_start_route.png' )  
-        }))
-        this.mapMarkEnd = new THREE.Mesh( planeGeo, new THREE.MeshBasicMaterial({
-            transparent:true, depthTest:false,
-            map: texLoader.load(Potree.resourcePath+'/textures/map_instruction_target_reached.png' )  
-        }))
-        this.mapMarkStart.renderOrder = this.mapMarkEnd.renderOrder = 2//在箭头之上 */
-         
-        let map2 = texLoader.load(Potree.resourcePath+'/textures/routePoint_map_fsna.png' ) 
-        this.mapArrowMats = {
-            default: new THREE.MeshBasicMaterial({
-                transparent:true, depthTest:false,
-                map:map2, 
-            }),
-            
-            fade: new THREE.MeshBasicMaterial({
-                transparent:true, depthTest:false,
-                map:map2, 
-                opacity:0.4
-            }), 
-        }
-        
-        
-        
-        this.mapArrow = new THREE.Mesh( planeGeo, this.mapArrowMats.default) 
-        this.mapArrow.scale.set(arrowSize,arrowSize,arrowSize)
-        this.mapArrows = new THREE.Object3D;
-        this.mapArrows.name = 'mapArrows'
-         
-        
-        
-        this.mapMeshGroup.add(this.mapArrows)
-        this.mapMeshGroup.name = 'mapRouteLayer'
-        this.mapMeshGroup.visible = false
-        
-        viewer.mapViewer.dispatchEvent({type:'add', object:this.mapMeshGroup, name:'route'})
-        this.mapArrow.layers.mask = this.mapArrows.layers.mask // 修改成和map中的layer一样的
-        
-        
-        
-        viewer.modules.SiteModel.bus.addEventListener('FloorChange',()=>{
-            if(this.routeStart && this.routeEnd){
-                this.updateOpacityAtMap()
-            }  
-        }) 
-        this.inited = true
-    }
-    
-    updateOpacityAtMap(){//只有当前楼层的透明度为1
-        var currentFloor = viewer.modules.SiteModel.currentFloor
-        //console.log('updateOpacityAtMap', currentFloor && currentFloor.name)
-        const lift = 0.3 // 因为发送请求时用的是floorPosition的高度,而它可能会到画好的floor之下,所以有误差
-        this.mapArrows.children.forEach((arrow,index)=>{
-            let pos = this.mapPoints[index].clone()
-                pos.z += lift  
-            let inSide = currentFloor && currentFloor.ifContainsPoint(pos)
-            arrow.material = inSide ? this.mapArrowMats.default : this.mapArrowMats.fade
-            //console.log('arrow',index, arrow.material.opacity)
-        }) 
-        
-        viewer.mapViewer.dispatchEvent('content_changed')
-    }//但是如果楼层刚好只框柱相机位置而没框住地面位置就不好了……
-    
-    
-    
-    
-    
-    createPole(polesMats, name){
-        const height = 1.5, sphereCount = 6, shadowSize = sphereSizeInfo.scale,  sphereSize = 0.04
-        
-        var group = new THREE.Object3D;
-            group.name = 'pole_'+name
-        var shadow = new THREE.Mesh(planeGeo,polesMats.shadowMat)
-        shadow.scale.set(shadowSize,shadowSize,shadowSize)
-        var sliceDis = height / (sphereCount+1);
-        group.add(shadow) 
-         
-        for(let i=0;i<sphereCount;i++){
-            var sphere = new Sprite({mat: polesMats.sphereMat}) 
-            sphere.position.set(0,0,sliceDis*(i+1))
-            sphere.scale.set(sphereSize,sphereSize,sphereSize);
-            sphere.visible = false
-            group.add(sphere)
-        }
-        
-        var hatSphere = new Sprite({mat: polesMats.hatMats[name], sizeInfo:sphereSizeInfo}) 
-        sphere.visible = false
-        hatSphere.position.set(0,0,height)
-        hatSphere.scale.copy(shadow.scale)
-        group.add(hatSphere)
-        return group
-    }
-    
-    
-    addTestArrow(){
-        
-    }
-    
-    addArrow(position){ 
-        var arrow = this.arrow.clone()
-        arrow.position.copy(position); 
-        this.arrows.add(arrow); 
-    }
-    addMapArrow(position){ 
-        var mapArrow = this.mapArrow.clone()
-        mapArrow.position.copy(position).setZ(0) 
-        this.mapArrows.add(mapArrow);
-    }
-    
-    
-    setArrowDir(arrows,index){
-        let arrow = arrows[index]
-        var nextOne = arrows[index+1];
-        var nextPos = nextOne ? nextOne.position : this.endPolePos //routeEnd
-        var direction = new THREE.Vector3().subVectors(arrow.position, nextPos).setZ(0);
-        //direction.normalize();
-        //console.log(direction.toArray())
-        var angle = Math.atan2(direction.y, direction.x ) + Math.PI/2 //Math.PI/2是因为贴图本身箭头方向不朝x
-        arrow.rotation.z = angle
-        //console.log(angle)
-    }
-    
-    
-     
-     
-    
-    setRouteStart(pos, dealZ , datasetId  ){
-        if(this.routeStart && pos && this.routeStart.equals(pos)) return //可能重复设置
-        this.routeStart = pos && new THREE.Vector3().copy(pos)  
-        if(dealZ && this.routeStart){
-            this.routeStart.setZ(this.getZAtMap()) 
-            this.bus && this.bus.emit('reposStartMarker', this.routeStart)
-        }
-        console.log('setRouteStart',this.routeStart&&this.routeStart.toArray()) 
-        
-        this.datasetIds[0] = datasetId
-        
-        //this.setStartPole(pos)
-        
-        this.generateRoute()
-        
-        
-    }
-    
-    setStartPole(pos){
-        this.startPolePos = pos
-        this.bus && this.bus.emit('reposStartMarker', pos)
-    }
-     
-    
-    setRouteEnd(pos, dealZ , datasetId  ){ 
-        if(this.routeEnd && pos && this.routeEnd.equals(pos)) return 
-        this.routeEnd = pos && new THREE.Vector3().copy(pos)
-        if(dealZ && this.routeEnd){
-            this.routeEnd.setZ(this.getZAtMap())
-            this.bus && this.bus.emit('reposEndMarker', this.routeEnd)
-        }
-        console.log('setRouteEnd',this.routeEnd&&this.routeEnd.toArray())        
-        this.datasetIds[1] = datasetId
-        //this.setEndPole(pos)
-        this.generateRoute()
-        
-    }
-    
-    
-    getZAtMap(){  
-        
-        //找到position.z与当前高度最接近的漫游点 
-        let result = Common.sortByScore(viewer.images360.panos,[],[e=> -(Math.abs(e.position.z - viewer.images360.position.z)) ])
-        let pano = result && result[0] && result[0].item
-        
-        return pano ? pano.floorPosition.z : viewer.bound.boundingBox.min.z + 1 
-        //若在平面图上画实在得不到当前楼层的,大概率是楼层画得不好,那就只能去获取当前楼层的了
-        
-        //navvis的高度取的是主视图所在楼层的中心高度(可能再高些)
-        
-    }
-    
-    setEndPole(pos){
-        this.endPolePos = pos
-        this.bus && this.bus.emit('reposEndMarker', pos)
-    }
-    
-    getSourceProjectionIndex(route) {//真正的起始
-        var e = route.findIndex(function(t) {
-            return t.instruction && t.instruction.type === 'source_projection_to_navgraph'
-        });
-        return e < 0 ? 0 : e
-    }
-    getDestinationProjectionIndex(route) {//真正的终点
-        var e = route.findIndex(function(t) {
-            return t.instruction && t.instruction.type === "destination_projection_to_navgraph"
-        });
-        return e < 0 ? route.length - 1 : e
-    }
-    
-    generateRoute(){
-        if(!this.routeStart || !this.routeEnd){ 
-            
-            return
-        }
-        
-        
-        //array.reduce(function(total, currentValue, currentIndex, arr), initialValue)
-        
-        
-        let create = ()=>{ 
-            this.routeLength = this.route.reduce((total, currentValue, currentIndex, arr)=>{
-                if(currentIndex == 0)return 0
-                return total + currentValue.distanceTo(arr[currentIndex-1]);
-            },0)
-            let count = Math.max(2,Math.round(this.routeLength / arrowSpacing))//点数
-            
-            const curve = new THREE.CatmullRomCurve3( this.route ); 
-            curve.curveType = 'chordal'//'centripetal'  'catmullrom'这个可能会超出路径外
-            this.curve = curve
-            
-            const scenePoints = curve.getSpacedPoints( count );//更平均
-            //const scenePoints = curve.getPoints( count );
-            scenePoints.splice(0,1);//去掉首尾
-            scenePoints.pop()
-            this.scenePoints = scenePoints
-            
-            this.updateMapArrows() 
-            this.displayRoute()
-            
-            {//map focus on this area
-                
-                const minBound = new THREE.Vector2(1,1)//针对垂直线,在地图上只有一个点
-                let bound = new THREE.Box2;
-                this.route.forEach(e=>{
-                    bound.expandByPoint(e)
-                })
-                let size = bound.getSize(new THREE.Vector2)
-                let markerSize = new THREE.Vector2(115,40) //起始和终点的标识呈长方形
-                let areaSize = viewer.mapViewer.viewports[0].resolution2
-                let areaArea = areaSize.x * areaSize.y
-                if(areaArea> 800 * 400){//是放大的 
-                    markerSize.multiplyScalar(areaArea / (800 * 400) /* / (size.x * size.y) */) 
-                }
-                let margin = size.clone().divide(viewer.mapViewer.viewports[0].resolution2).multiply(markerSize) ///边距 重点是起始和终点的标识占据较大
-                size.add(margin)
-                let center = bound.getCenter(new THREE.Vector2)
-                
-                size.x = Math.max(size.x, minBound.x )
-                size.y = Math.max(size.y, minBound.y )
-                let duration = 1000
-                viewer.mapViewer.moveTo(center, size, duration)
-            }
-            
-            this.bus.emit('gotResult', {dis:this.routeLength})
-            /* this.generateDeferred && this.generateDeferred.resolve({dis:this.routeLength})
-            this.generateDeferred = null */
-        }
-        
-        
-        if(Potree.fileServer){
-            let dealData = (data)=>{
-                
-                if(!data.data){
-                    console.log('没有数据')
-                    let result
-                    if(data && data.code == 4002){
-                        result = data;//正被修改数据集
-                    }else if(this.routeStart.distanceTo(this.routeEnd) < 1){
-                        result = { code: 500, msg: '距离太短,无法规划路线' }
-                    }else{
-                        result = { code: 500, msg: '超出数据集范围,无法规划路线' }
-                    }
-                    this.clearRoute() 
-
-
-                    this.setStartPole(this.routeStart) 
-                    this.setEndPole(this.routeEnd) 
-                    
-                    this.displayRoute() //还是要显示一下起始
-                    this.bus && this.bus.emit('gotResult', result )
-                    
-                    return //this.generateDeferred && this.generateDeferred.resolve()
-                }
-                
-                
-                data = data.data 
-                  
-                this.clearRoute()
-                let length = data.length
-                
-                if(length < 2){//可能距离太短 
-                    console.log('路径点数为'+length+',直接取起点和终点连线') 
-                    this.route = [this.routeStart, this.routeEnd];
-                }else{ 
-                    let startIndex = this.getSourceProjectionIndex(data)
-                    let endIndex = this.getDestinationProjectionIndex(data)
-                    
-                    
-                    let effectiveItems = data.slice(startIndex, endIndex + 1 );//只要点云范围内的点
-                    effectiveItems.forEach((item,i)=>{ 
-                        let pos = viewer.transform.lonlatToLocal.forward(item.location.slice(0))
-                        pos = new THREE.Vector3().fromArray(pos)//.setZ(item.z)
-                        this.route.push(pos)
-                    })
-                    
-                    console.log(this.route)
-                    
-                    
-                }
-                this.setStartPole(this.route[0]) 
-                this.setEndPole(this.route[this.route.length-1]) 
-                
-                create()
-                /*
-                    distance: 0.17581000000000116
-                    distance_to_previous: 0.17581000000000116
-                    id: 567
-                    instruction: {type: 'source_projection_to_navgraph'}
-                    latitude: 22.366605927999238
-                    location: (3) [113.5957510575092, 22.366605927999238, -1.12419]
-                    longitude: 113.5957510575092
-                    z: -1.12419
-                */
-            }
-            
-            
-            
-            
-            if(this.lastResult && (this.lastResult.data || this.lastResult.data.code != 4002)){//正被修改数据集的话要重新计算
-                let data = Common.CloneObject(this.lastResult.data) ,  use;  //直接用上次的结果
-                if(this.lastResult.routeStart.equals(this.routeStart) &&  this.lastResult.routeEnd.equals(this.routeEnd)){//和上次请求相同
-                    use = true 
-                }else if(this.lastResult.routeStart.equals(this.routeEnd) &&  this.lastResult.routeEnd.equals(this.routeStart)){//..反向
-                    use = true
-                    if(data.data){
-                        data.data = this.lastResult.data.data.slice(0).reverse()
-                    }    
-                }
-                if(use){
-                    console.log('直接用上次的结果')
-                    return setTimeout(()=>{dealData(data)}, 1)//延迟是为了等待获得 RouteGuider.generateDeferred
-                       
-                }
-                
-            }
-            
-            
-            
-            
-            let start = this.routeStart.clone();
-            let end = this.routeEnd.clone();
-            let startLonlat = viewer.transform.lonlatToLocal.inverse(start)
-            let endLonlat = viewer.transform.lonlatToLocal.inverse(end)
-            
-            var query = {
-                source_longitude: startLonlat.x,
-                source_latitude: startLonlat.y,
-                source_z: start.z,
-                destination_longitude: endLonlat.x,
-                destination_latitude: endLonlat.y,
-                destination_z: end.z
-            };
-            
-            
-            //let url = `/laser/route/${Potree.settings.number}/getRoute/${this.datasetIds[0]}/${this.datasetIds[1]}?`
-            let url = `/laser/route/${Potree.settings.number}/getRoute/${Potree.settings.originDatasetId}?`
-            for(let i in query){
-                url+= (i + '='+ query[i] +'&')
-            }
-            
-            Potree.fileServer.get(url).then((data)=>{
-                console.log(data.data)
-                if(!this.routeStart || !this.routeEnd)return 
-                
-                this.lastResult = {//保存数据
-                    routeStart : this.routeStart.clone(),
-                    routeEnd: this.routeEnd.clone(),
-                    data,
-                     
-                }
-                
-                dealData(data)
-                
-            })
-            
-            
-        }else{
-            //创个直线
-            /* const sliceDis = 1
-            let dis = this.routeStart.distanceTo(this.routeEnd);
-            let count = Math.max(2,Math.round(dis / sliceDis))//点数
-            let realSlideDis = dis / (count-1);
-            let dir = new THREE.Vector3().subVectors(this.routeEnd, this.routeStart).normalize().multiplyScalar(realSlideDis);
-            this.route = [this.routeStart];
-            for(let i=0;i<count-1;i++){
-                let lastOne = this.route[i];
-                this.route.push(new THREE.Vector3().addVectors(lastOne,dir))
-            }
-            this.route.splice(0,1) //route不用包含收尾 */
-            this.clearRoute()
-            this.route = [this.routeStart, this.routeEnd]
-            create()
-            
-        }
-          
-    }
-    
-    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))//点数
-        
-        if(count == this.mapPoints.length+1)return//没变
-
-        const mapPoints = this.curve.getSpacedPoints( count ); 
-        mapPoints.splice(0,1);//去掉首尾
-        mapPoints.pop() 
-        this.mapPoints = mapPoints
-        
-        
-        var scale = 25/zoom
-        this.mapArrow.scale.set(scale*0.6,scale*0.6,scale*0.6) 
-        /* this.mapMarkStart.scale.set(scale,scale,scale) 
-        this.mapMarkEnd.scale.set(scale,scale,scale)  */
-        
-        
-        if(ifReset){//因为缩放而重新排布箭头
-            this.clearRoute({resetMap:true})
-            this.displayRoute({resetMap:true}) 
-        }
-        this.updateOpacityAtMap()
-    }
-    
-    
-    updateArrowDisplay(){//根据当前位置更新显示一定范围内的箭头'
-    
-        if(this.scenePoints.length == 0)return
-        
-        /* var a = Common.sortByScore(this.scenePoints , null, [(point)=>{   //是否还要再requires里限制最远距离?
-            var playerPos = viewer.scene.getActiveCamera().position.clone().setZ(0)
-            
-            var pos = point.clone().setZ(0) 
-            
-            return -pos.distanceTo(playerPos);
-            
-        }]);
-        //获得展示的起始点 
-        let start = a[0].item
-        let startIndex = this.scenePoints.indexOf(start)
-        this.arrows.children.forEach((e,i)=>{
-            if(i<startIndex || i>startIndex+arrowsShowingCount)e.visible = false
-            else e.visible = true
-        }) */
-        
-        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
-        })
-        
-        
-    }
-    
-    
-    displayRoute(o={}){
-        if(!o.resetMap){ 
-            
-            this.poleStart.position.copy(this.startPolePos || this.routeStart)
-            this.poleEnd.position.copy(this.endPolePos || this.routeEnd)
-            /* this.mapMarkStart.position.copy(this.routeStart).setZ(0)
-            this.mapMarkEnd.position.copy(this.routeEnd).setZ(0) */
-            this.scenePoints.forEach(e=>this.addArrow(e))
-            this.arrows.children.forEach((e,i)=>this.setArrowDir(this.arrows.children,i));
-        }
-        this.sceneMeshGroup.traverse(e=>e.visible = true)  
-        this.mapMeshGroup.visible = true
-        this.mapPoints.forEach(e=>this.addMapArrow(e))
-        this.mapArrows.children.forEach((e,i)=>this.setArrowDir(this.mapArrows.children,i));
-        viewer.mapViewer.dispatchEvent({'type':'content_changed'})
-        this.updateArrowDisplay()
-    }
-    
-    clearRoute(o={}){
-        if(!o.resetMap){
-            this.routeLength = 0
-            this.route = []
-            this.scenePoints = []
-            this.mapPoints = []
-            let arrows = this.arrows.children.slice(0)
-            arrows.forEach(e=>{
-                this.arrows.remove(e)
-            })
-        } 
-        
-        let mapArrows = this.mapArrows.children.slice(0) 
-        mapArrows.forEach(e=>{
-            this.mapArrows.remove(e)
-        })
-        
-        this.sceneMeshGroup.traverse(e=>e.visible = false)  //包括sprite也要设置,防止update
-        this.mapMeshGroup.visible = false
-        viewer.mapViewer.dispatchEvent({'type':'content_changed'})
-    }
-    
-    clear(){//退出
-        console.log('导航clear') 
-        this.routeStart = null
-        this.routeEnd = null
-        this.clearRoute()
-        
-    }
-}
-
-//大概每十米要花一秒
-
-
-
-/* 
-
-    存在的问题:
-    路径不准确。起始点和终点偏移。
-
-
- */

+ 0 - 879
src/modules/siteModel/BuildingBox.js

@@ -1,879 +0,0 @@
-
-import * as THREE from "../../../libs/three.js/build/three.module.js";
-import {ctrlPolygon} from '../../objects/tool/ctrlPolygon.js'
-import {LineDraw, MeshDraw } from "../../utils/DrawUtil.js";  
-import math  from "../../utils/math.js";
-import Sprite from '../../objects/Sprite.js'
-/* import {config} from '../settings' */
-import searchRings from "../../utils/searchRings.js";
-import DepthBasicMaterial from "../../materials/DepthBasicMaterial.js";
-
-let texLoader = new THREE.TextureLoader() 
-
- 
-let markerMats
-let markerSizeInfo = {width2d:35}
-let color = new THREE.Color('#FFF')
-let faceMats
-let getFaceMat = (name)=>{
-    if(!faceMats){ //navvis材质可以搜gridTexture
-        let gridTex = texLoader.load( Potree.resourcePath+'/textures/gridmap.png' ) 
-            gridTex.wrapS = gridTex.wrapT = THREE.RepeatWrapping   
-            //gridTex.repeat.set(0.5,0.5)//放大一些
-        faceMats = { 
-            dataset: new THREE.MeshStandardMaterial({
-                color:812922,   
-                side:THREE.DoubleSide, 
-                opacity:0.2,
-                transparent:true,  
-                depthTest:false,
-                wireframe:true
-            }),
-            building: new THREE.MeshStandardMaterial({
-                color:812922,  metalness: 0.2, roughness:0.8,
-                side:THREE.DoubleSide, 
-                opacity:0.1,
-                transparent:true,  
-                depthTest:true
-            }),
-            buildingSelect: new THREE.MeshStandardMaterial({
-                color:36582,  metalness: 0, roughness:1,
-                side:THREE.DoubleSide,
-                opacity:0.1,
-                transparent:true,
-                depthTest:true
-            }),
-            floor:  new THREE.MeshStandardMaterial({
-                color:11708469,  metalness: 0.1, roughness:1,
-                side:THREE.DoubleSide,//BackSide,
-                opacity:0.05,
-                transparent:true,
-                depthTest:true, 
-            }),
-             
-            /* floorSelect: new THREE.MeshStandardMaterial({
-                color:16707151,  metalness: 0, roughness:1,
-                side:THREE.DoubleSide,
-                opacity:1,
-                transparent:true,
-                depthTest:true,
-                polygonOffset : true,//是否开启多边形偏移 
-				polygonOffsetFactor : -0.75,//多边形偏移因子
-				polygonOffsetUnits : -4.0,//多边形偏移单位 
-                map: gridTex,
-            }),  */ 
-            floorSelect: new DepthBasicMaterial({
-                map: gridTex,
-                color:16707151,  
-                side:THREE.DoubleSide,//BackSide, 
-                opacity:1,
-                transparent:true, 
-                useDepth : true,
-                /* polygonOffset : true,//是否开启多边形偏移 
-				polygonOffsetFactor : -0.75,//多边形偏移因子
-				polygonOffsetUnits : -4.0,//多边形偏移单位  */
-                
-                clipDistance : 1, occlusionDistance:1, /* occlusionDistance:变为backColor距离, clipDistance:opacity到达0或者1-maxClipFactor时的距离 */  
-                maxClipFactor:0.4, backColor:'#efe' //backColor:"#669988"  ,
-                  
-            }),
-            
-            room: new THREE.MeshStandardMaterial({
-                color:"#ff44ee",  metalness: 0, roughness:1,
-                side:THREE.DoubleSide,//BackSide,
-                opacity:0.08,
-                transparent:true, 
-                depthTest:false, 
-            }), 
-            /* roomSelect: new THREE.MeshStandardMaterial({
-                color:"#ff44ee",  metalness: 0.3, roughness:1,
-                side:THREE.DoubleSide,//BackSide,
-                opacity:1,
-                transparent:true,
-                depthTest:true,
-                polygonOffset : true,//是否开启多边形偏移.(开启是因为和floor重叠了会闪烁)
-				polygonOffsetFactor : -0.75,//多边形偏移因子
-				polygonOffsetUnits : -4.0,//多边形偏移单位  
-                map: gridTex,
-            }), */
-            roomSelect: new DepthBasicMaterial({
-                map: gridTex,
-                color:"#ff44ee", 
-                side:THREE.DoubleSide,//BackSide, 
-                opacity:1,
-                transparent:true, 
-                useDepth : true,
-                /* polygonOffset : true,//是否开启多边形偏移 
-				polygonOffsetFactor : -0.75,//多边形偏移因子
-				polygonOffsetUnits : -4.0,//多边形偏移单位  */
-                
-                clipDistance : 1, occlusionDistance:0.5, /* occlusionDistance:变为backColor距离, clipDistance:opacity到达0或者1-maxClipFactor时的距离 */  
-                maxClipFactor:0.6, backColor:'#ff88dd'//"#cc99c2"  ,
-                 
-            })
-        }
-    }
-    return faceMats[name]
-}
-
-
-
- 
-
-export class BuildingBox extends ctrlPolygon{//建筑实体,包括building, floor, room
-    constructor(prop) {
-        prop.dimension = '3d'
-        //prop.name = Potree.config.siteModel.names[prop.buildType] + 
-         
-        super('siteModel_'+prop.buildType,  prop);
-        
-         
-        
-        this.midMarkers = []
-        this.buildChildren = []//子实体
-        this.holes = [] //在这创建的hole
-        this.parentHoles = [];//floor从building那得到的当层holes
-        this.mats = {} //材质
-        
-        this.panos = this.panos || [];
-        this.center //中心点
-        
-        if(this.buildType=='floor'){
-            
-            this.points = prop.points = this.buildParent.points;//完全等于建筑的点
-            this.buildParent.holes.forEach(hole=>{//从building获取holes
-                let floorHole = new BuildingBox({
-                    buildType : 'hole', 
-                    buildParent:this,
-                    originHole : hole, //整栋大楼在当层的hole
-                    ifDraw: this.ifDraw  || Potree.settings.drawEntityData
-                });
-                this.parentHoles.push(floorHole)
-                this.add(floorHole) 
-                
-                floorHole.points = hole.points//完全等于建筑的点
-            })
-        } 
-        if(this.buildType == 'room' || this.buildType == 'hole'){
-            this.restrictArea = this.buildParent  //不能超出的区域
-        }
-        
-        if(this.ifDraw){ //只存储空间模型信息,不绘制
-            if(this.buildType != 'hole'){
-                this.box = this.createBox()
-                this.add(this.box)
-            }
-            {
-                this.lineMesh = LineDraw.createLine([],{color})
-                this.lineMesh.name = 'buildingLines'
-                this.lineMesh.visible = false            
-                this.add(this.lineMesh) 
-                viewer.setObjectLayers(this.lineMesh, 'bothMapAndScene' ) 
-            }
-            
-            
-            this.addEventListener('dragChange',(e)=>{ //修改中点
-                this.updateTwoMidMarker(e.index)
-            }) 
-            
-        }
-        
-        this.initData(prop)
-        
-        
-    } 
-    
-    
-    initData(prop){
-        if(prop.ifDraw){
-            super.initData(prop) 
-        }else{
-            if(prop.points){
-                this.points = prop.points  
-            }
-            
-            
-        }
-        
-    } 
-    
-    intersectPointcloudVolume(pointcloud){//和pointcloud的重叠体积
-        var bound = this.getBound()
-        let bound2 = pointcloud.bound;
-        if(!bound.intersectsBox(bound2)) return 0;
-        
-        
-        let {zMin , zMax} =  this.getRealZ()
-        let min = Math.min(zMin, bound2.min.z);
-        let max = Math.max(zMax, bound2.max.z); 
-        let height1 = zMax - zMin
-        let height2 = bound2.max.z-bound2.min.z
-        let coverHeight = height1 + height2 - (max-min)//重叠高度 <=0是没重叠
-         
-        let boxPoints = pointcloud.getUnrotBoundPoint() //获取tightBound的四个点。 如果是有旋转角度的点云,这个和pointcloud.bound的四个点是不一致的,覆盖面积小于pointcloud.bound
-       
-        let areaWhole = 0  
-        let area1 = this.getArea()
-        let area2 = Math.abs(math.getArea(boxPoints))
-         
-        {//计算points与点云总面积 (但是把hole也加入了面积)(并集,重叠部分只算一次)  
-            let rings = math.getPolygonsMixedRings([this.points, boxPoints] )
-            
-            rings.forEach(e=>{ 
-                areaWhole+=e.area
-            })
-        }
-        
-        let coverHoleArea = 0 //holes与数据集重叠的部分
-        let holes = this.holes.concat(this.parentHoles)
-        let holesArea = 0    //所有holes面积相加
-        let areaHoleWithPointcloud = 0 //hole和点云的面积并集
-        
-        if(holes.length>0){//还要再扣除holes与数据集重叠的部分。其中holes为mix轮廓
-            let outHoles = []//没有重合的holes的外轮廓
-            /* if(holes.length>=2){//合并holes。如果能在绘制时直接合并holes就好啦,这步就转移到那去,但是要删除hole好麻烦
-                  
-                let holes_ = holes.map(e=>e.points)
-                
-                outHoles = math.getPolygonsMixedRings(holes_,  true )
-                outHoles.forEach(e=>{ 
-                    holesArea+=e.area
-                }) 
-                outHoles = outHoles.map(e=>e.points)
-                
-                
-            }else{
-                outHoles = holes.map(e=>e.points)
-                outHoles.forEach(e=> holesArea += Math.abs(math.getArea(e)))                
-            } */
-            holesArea = this.getHolesArea()
-            
-            //holes与数据集重叠的部分
-            
-            {    
-                let polygons = outHoles.concat([boxPoints]) 
-                let rings = math.getPolygonsMixedRings(polygons)
-                rings.forEach(e=>{ 
-                    areaHoleWithPointcloud+=e.area
-                })
-                coverHoleArea = holesArea + area2 - areaHoleWithPointcloud//hole和点云的交集
-            }
-             
-        }
-        
-        
-        let coverArea = area1 + area2 - areaWhole - coverHoleArea; //重叠面积
-         
-        return coverArea * coverHeight
-    }
-    
-    
-    addHole(points=[]){  
-        let prop = {
-            buildType : 'hole',
-            zMin : this.zMin,
-            zMax : this.zMax,
-            points, 
-            buildParent:this,
-            ifDraw: this.ifDraw || Potree.settings.drawEntityData
-        }
-        //hole的zMin zMax跟随buildParent
-        var hole = new BuildingBox(prop);
-        this.holes.push(hole)
-        
-        if(this.buildType == 'building'){//为每一层添加对应的hole
-            this.buildChildren.forEach(floor=>{
-                let floorHole = new BuildingBox({
-                    buildType : 'hole', 
-                    zMin : this.zMin,
-                    zMax : this.zMax,
-                    buildParent:floor,
-                    originHole : hole, //整栋大楼在当层的hole
-                    ifDraw: this.ifDraw  || Potree.settings.drawEntityData
-                });
-                floor.parentHoles.push(floorHole)
-                floor.add(floorHole)
-                floorHole.points = hole.points//完全等于建筑的点
-            })
-            
-        }
-        
-        this.add(hole);//直接加在这,不加meshGroup了
-        this.update() //update box mesh
-        return hole
-        
-        //hole不创建box,只有它的buildParent需要更新box。 但有线条和marker.  hole不在buildChildren里,但有buildParent
-        
-    }
-    
-    
-    removeHole(hole){// 这个hole不会是parentHoles里的。
-        hole.dispose()
-        
-        if(this.buildType == 'building'){ //若是整栋大楼的hole,在每层去除它的对应hole
-            this.buildChildren.forEach(floor=>{ 
-                let holeAtFloor = floor.parentHoles.find(e=>e.originHole == this )
-                let index = floor.parentHoles.indexOf(holeAtFloor)  
-                index > -1 && floor.parentHoles.splice(index, 1)                
-                holeAtFloor.dispose() 
-            })
-        } 
-        
-        let index = this.holes.indexOf(hole)
-        if(index>-1){
-            this.holes.splice(index, 1)
-        }
-        this.remove(hole)
-        this.update()
-    }
-    
-    
-    
-    
-    createBox(){ 
-        var geometry = new THREE.Geometry();
-        
-        
-        
-        this.mats.boxDefault = getFaceMat(this.buildType)  
-        this.mats.boxSelected = getFaceMat(this.buildType+'Select')     
-        
-        
-        var mesh = new THREE.Mesh(geometry, this.mats.boxDefault)
-        mesh.name = 'buildingBox';
-        if(this.buildType == 'floor'){
-            viewer.setObjectLayers(mesh, 'siteModelMapUnvisi' ) //楼层默认在地图不显示,为了不会叠加透明度
-        }else{
-            viewer.setObjectLayers(mesh, 'bothMapAndScene' )
-        }
-         
-        
-        
-        //mesh.frustumCulled = false;
-        return mesh
-    }
-    
-    
-    
-    addMarker(o={} ){
-        if(this.buildType=='floor')return; //楼层不需要marker
-        
-        let marker = new Sprite({mat:this.getMarkerMaterial('default'), renderOrder : 3, sizeInfo: markerSizeInfo, dontFixOrient: true, name:"building_marker"} )
-       
-         
-        viewer.setObjectLayers(marker, 'siteModeOnlyMapVisi' ) 
-        
-        o.marker = marker
-        super.addMarker(o)
-        
-        if(!this.selected)viewer.updateVisible(marker,'select',false) 
-         
-        let addClickEvent = (e)=>{ 
-            let click = (e) => {   
-                this.dispatchEvent({type:'clickMarker', marker } )  //由entity发送给sitemodel统一处理
-            }; 
-            marker.addEventListener('click', click); 
-            marker.addEventListener('clickSelect', (e)=>{
-                 this.setMarkerSelected(marker, e.state ? 'select' : 'unselect' );  
-            }); 
-            marker.removeEventListener('addHoverEvent',addClickEvent) 
-        }
-        marker.addEventListener('addHoverEvent',addClickEvent)//当非isNew时才添加事件
-        if(!this.isNew){
-            marker.dispatchEvent('addHoverEvent')
-        }
-     
-        return marker
-    }
-    
-    removeMarker(index){
-        super.removeMarker(index);
-        if(!this.isNew){
-            //重新添加midMarkers 
-            this.midMarkers.forEach(e=>this.remove(e));
-            this.midMarkers = [] 
-            this.addMidMarkers() 
-        }
-        
-        this.update();  
-        if(this.points.length == 2 && this.box){//清除原先length>=3时候的
-            this.box.geometry = new THREE.Geometry();
-        } 
-        
-     
-    }
-    
-    addMidMarker(index, point){
-        if(this.buildType=='floor')return; //楼层不需要marker
-        let marker = new Sprite({mat:this.getMarkerMaterial('midPrepare'), sizeInfo: markerSizeInfo, dontFixOrient: true, name:"building_midMarker"} )
-        this.midMarkers = [...this.midMarkers.slice(0,index), marker, ...this.midMarkers.slice(index,this.midMarkers.length)]
-        
-        marker.renderOrder = 3 
-         
-        viewer.setObjectLayers(marker, 'siteModeOnlyMapVisi' ) 
-        { // Event Listeners  
-            let mouseover = (e) => {
-                this.setMarkerSelected(e.object, 'hover', 'single'); 
-                viewer.dispatchEvent({
-                    type : "CursorChange", action : "add",  name:"markerMove"
-                }) 
-            };
-            let mouseleave = (e) => {
-                this.setMarkerSelected(e.object, 'unhover', 'single');
-                viewer.dispatchEvent({
-                    type : "CursorChange", action : "remove",  name:"markerMove"
-                })
-            }
-            let drag = (e) => {
-                let index = this.midMarkers.indexOf(marker)
-                let newMarker = this.addMarker({index:(index+1), point:marker.position.clone()  }) 
-                this.addMidMarker(index+1, new THREE.Vector3 )
-                this.updateTwoMidMarker(index+1) 
-                this.setMarkerSelected(marker, 'unhover') 
-                viewer.inputHandler.startDragging(newMarker , {/* dragViewport:viewer.mapViewer.viewports[0],  */   } ); //notPressMouse代表不是通过按下鼠标来拖拽.  dragViewport指定了只能在地图上拖拽
-            }
-            marker.addEventListener('drag', drag );
-            //marker.addEventListener('drop', drop);
-            marker.addEventListener('mouseover', mouseover);
-            marker.addEventListener('mouseleave', mouseleave);
-        }
-        this.add(marker)
-        this.updateMarker(marker, point)
-        if(!this.selected)viewer.updateVisible(marker,'select',false) 
-        return marker
-    }
-    
-    
-    
-    
-    
-    addMidMarkers(){//第一次画好所有marker后,一次性为线段增加中点marker
-        let length = this.points.length
-        this.points.forEach((point,index)=>{
-            let nextPoint = this.points[(index+1)%length]
-            let midPoint = new THREE.Vector3().addVectors(point, nextPoint).multiplyScalar(0.5)
-            this.addMidMarker(index, midPoint )
-        })
-    }
-    
-    updateTwoMidMarker(index){//更新第index个marker两边的midMarker
-        if(!this.midMarkers.length)return
-        let length = this.points.length
-        let last = this.points[(index-1+length)%length] //它之前的marker位置
-        let next = this.points[(index+1)%length];//它之后的marker位置
-        let current = this.points[index]//当前位置 
-        let lastMid = new THREE.Vector3().addVectors(last, current).multiplyScalar(0.5)//上一个中点
-        let nextMid = new THREE.Vector3().addVectors(next, current).multiplyScalar(0.5)//下一个中点
-        let lastMidMarker = this.midMarkers[(index-1+length)%length];
-        let nextMidMarker = this.midMarkers[index]
-        this.updateMarker(lastMidMarker, lastMid) 
-        this.updateMarker(nextMidMarker, nextMid) 
-    }
-    
-     
-    
-    
-    
-    dispose(){//销毁geo、remove from parent
-        super.dispose()
-        this.box && this.box.geometry.dispose();
-        this.lineMesh && this.lineMesh.geometry.dispose();
-        this.holes.forEach(e=>e.dispose()) 
-        this.parentHoles.forEach(e=>e.dispose()) 
-        //this.buildChildren.forEach(e=>e.dispose())
-        this.dispatchEvent('dispose')
-    }
-    
-    
-    
-    updateBox(){
-        if(!this.box)return
-        this.box.geometry.dispose()
-        var shrink = this.buildType == 'room' ? 0.11 : this.buildType == 'floor' ?  0.082 :  0.2   ;//防止mesh重叠冲突(给一个不寻常的数字)  但离远了还是会有点闪烁
-        if(this.points.length >= 3){ 
-            let holes = this.holes.concat(this.parentHoles)
-            let holesPoints = holes.filter(e=>e.points.length>2).map(e=>e.points)
-            this.box.geometry = MeshDraw.getExtrudeGeo(this.points, holesPoints, {
-                depth:this.zMax-this.zMin-shrink,
-                UVGenerator: new MetricUVGenerator()
-            }) 
-            if(this.buildType == 'building' ){
-                this.box.position.z = this.zMin - shrink / 2  
-            }else{
-                this.box.position.z = this.zMin + shrink / 2 
-            }
-             
-        }
-    }
-    
-     
-    
-    update(options={}){ 
-        super.update(this.buildType != 'floor' && options.ifUpdateMarkers)
-        let length = this.points.length
-        
-        
-       
-        {//确保一下一样
-            if(this.originHole){ 
-                this.points = this.originHole.points //完全等于building的hole
-            }
-            if(this.buildType == 'hole'){
-                this.zMin = this.buildParent.zMin;
-                this.zMax = this.buildParent.zMax;
-            } 
-        }
-        
-        
-        
-        if(!options.dontUpdateBox){
-            let boxOwner
-            if(this.buildType == 'hole'){
-                if(this.buildParent.buildType == 'building'){ //若是整栋大楼的hole,在每层都要更新下它的对应hole
-                    this.buildParent.buildChildren.forEach(floor=>{
-                        let holeAtFloor = floor.parentHoles.find(e=>e.originHole == this ) 
-                        holeAtFloor && holeAtFloor.update()  //刚开始创建时还没创建对应的 holeAtFloor会为null
-                    })
-                } 
-                boxOwner = this.buildParent 
-            }else{
-                boxOwner = this
-            }
-            boxOwner.updateBox()
-        }
-        
-        
-        
-        {//update lines
-            
-            let positions = [];
-           
-            this.points.forEach((point, index)=>{
-                
-                //竖线:
-                positions.push(point.clone().setZ(this.zMin), point.clone().setZ(this.zMax))
-                
-                //横线
-                let nextPoint = this.points[(index+1)%length]; 
-                if(!nextPoint)return;//when length==1
-                
-                positions.push(point.clone().setZ(this.zMax), nextPoint.clone().setZ(this.zMax))//上横线
-                positions.push(point.clone().setZ(this.zMin), nextPoint.clone().setZ(this.zMin))//下横线
-            }) 
-            
-            LineDraw.moveLine(this.lineMesh,positions)
-             
-        }
-        
-        if(!options.dontUpdateChildren){
-            if(this.buildType == 'building'  ){
-                this.buildChildren.forEach(floor=>{
-                    floor.points = this.points 
-                    floor.update()
-                })
-                
-            } 
-            
-            { 
-                let holes = this.holes.concat(this.parentHoles) 
-                holes.forEach(hole=> {  
-                    
-                    hole.update({dontUpdateBox:true})//父级更新了box,hole就不需要更新box了
-                }) 
-                    
-            } 
-        
-        } 
-    }
-    
-    
-     
-    
-    
-    
-    getHolesArea(){
-        let holes = this.holes.concat(this.parentHoles)
-        let outHoles, holesArea = 0
-        if(holes.length>=2){//合并holes。如果能在绘制时直接合并holes就好啦,这步就转移到那去,但是要删除hole好麻烦
-              
-            let holes_ = holes.map(e=>e.points)
-            
-            outHoles = math.getPolygonsMixedRings(holes_,  true )
-            outHoles.forEach(e=>{ 
-                holesArea+=e.area
-            }) 
-            outHoles = outHoles.map(e=>e.points)
-            
-            
-        }else{
-            outHoles = holes.map(e=>e.points)
-            outHoles.forEach(e=> holesArea += Math.abs(math.getArea(e)))                
-        }
-        return holesArea
-        
-    }
-    
-    getArea(ifRidOfHoles){//面积
-        //不排除hole
-        return Math.abs(math.getArea(this.points)) - (ifRidOfHoles ? this.getHolesArea() : 0)
-    }
-    
-    getVolume(ifRidOfHoles){//体积
-        let {zMin , zMax} = this.getRealZ()
-        let height = zMax - zMin;
-        if(isNaN(height))height = 0
-        return this.getArea(ifRidOfHoles) * height
-    
-    }
-    
-    getRealZ(){//求真实高度时用到的
-        let zMin , zMax
-        if (this.buildType == 'building') {
-            //building的zMax和zMin一样的所以要算
-            let top = this.buildChildren[this.buildChildren.length - 1]
-            let btm = this.buildChildren[0] 
-            zMin = btm ? btm.zMin : 0  //建好的建筑不加楼的话是0
-            zMax = top ? top.zMax : 0
-        }else if(this.buildType == 'hole'){
-            return this.buildParent.getRealZ()
-        }else{
-            zMin = this.zMin,  zMax = this.zMax
-        }
-        return {zMin,zMax}
-    }
-    
-    
-    /* getDrawZ(){ //画线和box时用到的z
-        let zMin , zMax
-        if(this.buildType == 'hole'){
-             if(this.buildParent.buildType == 'building' && atFloor){ 
-                 zMin = atFloor.zMin,  zMax = atFloor.zMax 
-             }else{
-                 zMin = this.buildParent.zMin,  zMax = this.buildParent.zMax
-             }
-        }else{
-            zMin = this.zMin,  zMax = this.zMax
-        }
-        
-        return {zMin, zMax}
-        
-    } */
-    
-    
-    
-    getBound(){
-        let bound = new THREE.Box3
-         
-        let {zMin , zMax} = this.getRealZ()
-        
-        let points = this.buildType == 'floor' ? this.buildParent.points : this.points
-        points.forEach(p=>{
-            bound.expandByPoint(p.clone().setZ(zMin))
-            bound.expandByPoint(p.clone().setZ(zMax))
-        }) 
-        return bound
-    }
-    
-     
-    getMarkerMaterial(type) {
-        if(!markerMats){
-            markerMats = {  
-                default:    new THREE.MeshBasicMaterial({  
-                    transparent: !0,
-                    color,
-                    opacity: 0.8,
-                    map: texLoader.load(Potree.resourcePath+'/textures/whiteCircle.png' ),  
-                    depthTest:false,
-                    
-                }),
-                midPrepare:    new THREE.MeshBasicMaterial({ //线中心的半透明点  
-                    transparent: !0,
-                    color,
-                    opacity: 0.4,
-                    map: texLoader.load(Potree.resourcePath+'/textures/whiteCircle.png' ), 
-                    depthTest:false,
-                }),  
-                hover:    new THREE.MeshBasicMaterial({   
-                    transparent: !0,
-                    color,
-                    opacity: 1,
-                    map: texLoader.load(Potree.resourcePath+'/textures/whiteCircle.png' ), 
-                    depthTest:false,
-                     
-                }),
-                select:    new THREE.MeshBasicMaterial({   
-                    transparent: !0,
-                    color:new THREE.Color('#00C8AF'),
-                    opacity: 1,
-                    map: texLoader.load(Potree.resourcePath+'/textures/whiteCircle.png' ), 
-                    depthTest:false,
-                     
-                }),   
-            }
-            
-        }
-        return markerMats[type]
-        
-    }
-    
-    
-    setMarkerSelected(marker, state, hoverObject){ 
-        //console.warn(marker.id , state, hoverObject)
-         
-        
-        if(state == 'select'){
-            marker.selected = true
-            marker.material = this.getMarkerMaterial('select')
-        }else if(state == 'unselect'){
-            marker.selected = false
-            marker.material = this.getMarkerMaterial('default')
-        }else{
-            if(marker.selected)return //选中时不允许修改为除了'unselect'以外的状态
-            
-            if(state == 'hover'){
-                marker.material = this.getMarkerMaterial('hover')
-            }else if(state == 'unhover'){
-                if(marker.name.includes('mid')){
-                    marker.material = this.getMarkerMaterial('midPrepare')
-                }else{
-                    marker.material = this.getMarkerMaterial('default')
-                } 
-            }
-        }
-    }
-    
-    
-    select(){
-        //最多再显示一层子级的线,如building不会显示room中的hole的线
-        //box是一直显示的,但会切换材质 
-        
-        /* 
-            选中                  box                                     线
-            
-            building            自己(底盘)选中                 自己, floor不带hole
-        
-            floor               自己选中                         自己, room不带hole
-            
-            room                自己选中                         自己   
-        
-         */  //注:自己的就代表定包括hole,如果有parentHoles的也(building上的hole的对应)
-        
-        
-        //console.log('select '+this.name,   this.selected)
-        
-        if(this.selected)return
-        
-        if(this.box){
-            this.box.material = this.mats.boxSelected;
-        }
-        
-        if(this.buildType == 'building'|| this.buildType == 'floor'){
-            this.buildChildren.forEach(e=>{
-                e.lineMesh.visible = true
-            })
-              
-            if(this.buildType == 'floor'){
-                viewer.setObjectLayers(this.box, 'bothMapAndScene' ) 
-                viewer.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' )
-        }
-        
-        
-        
-        
-        
-        this.lineMesh.visible = true
-        this.markers && this.markers.forEach(e=>viewer.updateVisible(e,'select',true) )
-        this.midMarkers && this.midMarkers.forEach(e=>e.visible = true)
-        
-        let holes = this.holes.concat(this.parentHoles)
-        holes.forEach(e=>e.select()) 
-        
-        this.selected = true
-        this.dispatchEvent({type:'select'})
-    }
-    
-    
-    unselect(){
-        if(!this.selected)return
-        //console.log('unselect '+this.name  )
-        if(this.box){
-            this.box.material = this.mats.boxDefault;
-        }
-        
-        if(this.buildType == 'building' || this.buildType == 'floor'){ 
-            this.buildChildren.forEach(e=>{  //(这里要保证选中前要先取消选中,否则如选中房间后取消了楼层,房间线就隐藏了)
-                e.lineMesh.visible = false
-            })  
-            
-            if(this.buildType == 'floor'){
-                viewer.setObjectLayers(this.box, 'siteModelMapUnvisi' ) 
-                viewer.setObjectLayers(this.buildParent.box, 'bothMapAndScene' ) 
-            }
-            
-        }else if(this.buildType == 'room'){
-            viewer.setObjectLayers(this.buildParent.box, 'siteModelMapUnvisi' )
-            viewer.setObjectLayers(this.buildParent.buildParent.box, 'bothMapAndScene' )
-        }
-        
-        this.lineMesh.visible = false
-        this.markers && this.markers.forEach(e=>viewer.updateVisible(e,'select',false) )
-        this.midMarkers && this.midMarkers.forEach(e=>e.visible = false)
-        
-        let holes = this.holes.concat(this.parentHoles)
-        holes.forEach(e=>e.unselect()) 
-        
-        this.selected = false
-        this.dispatchEvent({type:'unselect'})
-    }
-    
-     
-    
-    
-    ifContainsPoint(position){//看它所定义的空间是否包含某个坐标(要排除hole)
-    
-        let {zMin , zMax} = this.getRealZ()
-        if(position.z < zMin ||  position.z > zMax   ) return
-    
-        let holes = this.holes.concat(this.parentHoles)
-        let holesPoints = holes.filter(e=>e!=this && e.points.length>2).map(e=>e.points) 
-        let inShape = math.isPointInArea(this.points, holesPoints, position) 
-        
-         
-        return !!inShape 
-    }
-     
-}
-
-
-
-
-
-class MetricUVGenerator{
-    constructor(){
-        this.a = new THREE.Vector3,
-        this.b = new THREE.Vector3,
-        this.c = new THREE.Vector3,
-        this.d = new THREE.Vector3
-    }
-    generateTopUV(t, e, n, r, o) {
-        return [new THREE.Vector2(e[3 * n],e[3 * n + 1]), new THREE.Vector2(e[3 * r],e[3 * r + 1]), new THREE.Vector2(e[3 * o],e[3 * o + 1])]
-    }
-    
-    generateSideWallUV(t, e, n, r, o, a) {
-        var s = e;
-        this.a.set(s[3 * n], s[3 * n + 1], s[3 * n + 2]),
-        this.b.set(s[3 * r], s[3 * r + 1], s[3 * r + 2]),
-        this.c.set(s[3 * o], s[3 * o + 1], s[3 * o + 2]),
-        this.d.set(s[3 * a], s[3 * a + 1], s[3 * a + 2]);
-        var c = this.a.x !== this.b.x
-          , l = c ? this.b : this.d
-          , u = this.a.distanceTo(l)
-          , d = l.distanceTo(this.c);
-        return [new THREE.Vector2(this.a.x,0), c ? new THREE.Vector2(this.a.x + u,0) : new THREE.Vector2(this.a.x,d), new THREE.Vector2(this.a.x + u,d), c ? new THREE.Vector2(this.a.x,d) : new THREE.Vector2(this.a.x + u,0)]
-    }
-}
- 

File diff suppressed because it is too large
+ 0 - 1280
src/modules/siteModel/SiteModel.js


+ 0 - 121
src/objects/Axis.js

@@ -1,121 +0,0 @@
-
-
-import * as THREE from "../../libs/three.js/build/three.module.js"; 
-import {MeshDraw,LineDraw} from '../utils/DrawUtil.js'
- 
-/*  
-
-                 z   
-                 |
-                 |
-                 |
-                 | 
-       x <-------|   中心为点云position加boudingbox中心
-                /
-               /
-             y
-
- */
- 
-var lineLen = 2, stemLen = 4, arrowLen = 2, lineDisToStem = 5;
-var opacity = 0.5
-export default class Axis extends THREE.Object3D {// 坐标轴
-	constructor (position) {
-		super()
-        this.getArrow() 
-        this.createArrows()
-        //this.position.copy(position) 点云的中心点就是在(0,0,0)
-        //this.scale.set(2,2,2)
-    }
-    getArrow(){
-        var arrowGroup = new THREE.Object3D()
-        
-        
-        
-        var line = LineDraw.createLine([new THREE.Vector3, new THREE.Vector3(0,0,lineLen)])
-        var stem = new THREE.Mesh(new THREE.BoxGeometry(0.3, 0.3, stemLen)) 
-            stem.position.set(0,0,lineLen+lineDisToStem+stemLen/2);
-        var arrow = new THREE.Mesh(new THREE.CylinderBufferGeometry( 0, 0.6, arrowLen, 12, 1, false ));//radiusTop = 1, radiusBottom = 1, height = 1, radialSegments = 8, heightSegments = 1, openEnded = false, thetaStart = 0, thetaLength = Math.PI * 2
-            arrow.position.set(0,0,lineLen+lineDisToStem+stemLen + arrowLen/2);
-            arrow.rotation.set(Math.PI/2,0,0)
-            
-        arrowGroup.add(stem)
-        arrowGroup.add(line)
-        arrowGroup.add(arrow)
-        
-        this.arrowGroup = arrowGroup
-        
-    } 
-    
-    
-    
-    createArrows(){ 
-
-
-        var material = new THREE.MeshBasicMaterial({color:"#00d7df",side:2,transparent:true,opacity:0.8, depthWrite:false});
-        let axis = Object.keys(Potree.config.axis)
-        axis.forEach((axisText)=>{
-            let color =  Potree.config.axis[axisText].color
-            var group = this.arrowGroup.clone()
-            
-            group.children.forEach(e=>{
-                e.material = e.material.clone()
-                /* e.material.opacity = opacity
-                e.material.transparent = true */
-                e.material.color.set(color)
-            })  
-            
-            var label = this.createLabel(axisText, color)  
-                label.position.set(0, 0, lineLen + stemLen + arrowLen + lineDisToStem + 3);
-                group.add(label) 
-        
-
-            if(axisText == 'y'){
-                group.rotation.x = -Math.PI / 2
-            }else if(axisText == 'x'){
-                group.rotation.y = Math.PI / 2
-            } 
-            
-            this.add(group)
-        }) 
-        
-    }
-
-    createLabel(text,color){
-        var canvas = document.createElement("canvas")
-        var context = canvas.getContext("2d");
-        canvas.width = 256,
-        canvas.height = 256; 
-        var fontSize = 120  
-        context.fillStyle =  color //"#00ffee";
-        context.font = "normal " + fontSize + "px 微软雅黑" 
-        var textWidth = context.measureText(text).width; 
-        context.clearRect(0,0,canvas.width,canvas.height);
-        context.fillText(text, (canvas.width - textWidth) / 2 , (canvas.height + fontSize) / 2);
-         
-        var tex = new THREE.Texture(canvas); 
-        tex.needsUpdate = true
-
-
-        tex.minFilter = THREE.NearestFilter//防止边缘发黑
-        tex.magFilter = THREE.NearestFilter//防止边缘发黑
-        var sprite = new THREE.Sprite(new THREE.SpriteMaterial({ 
-            map: tex  , // depthWrite:false,
-             
-        })) 
-        
-        sprite.renderOrder = 1//防止在透明后还是出现白矩形挡住其他mesh
-        sprite.scale.set(3,3,3)
-        return sprite
-       
-    }
-   
-}
-
-
-
-
-
-
-
-

+ 0 - 141
src/objects/InfiniteGridHelper.js

@@ -1,141 +0,0 @@
-// Author: Fyrestar https://mevedia.com (https://github.com/Fyrestar/THREE.InfiniteGridHelper)
-import * as THREE from "../../libs/three.js/build/three.module.js";
-
-
-
-class InfiniteGridHelper extends THREE.Mesh{
-     
-    constructor(size1, size2, color, distance, opacity1=0.2, opacity2=1){
-        
-        color = color || new THREE.Color('white');
-        size1 = size1 || 10;
-        size2 = size2 || 100;
-
-        distance = distance || 8000; //可视距离?越远越模糊
-
-        const geometry = new THREE.PlaneBufferGeometry(2, 2, 1, 1);
-
-        const material = new THREE.ShaderMaterial({
-
-            side: THREE.DoubleSide,
-
-            uniforms: {
-                uSize1: {
-                    value: size1
-                },
-                uSize2: {
-                    value: size2
-                },
-                
-                opacity1:{//线条1的
-                    value: opacity1
-                },
-                opacity2:{//线条2的
-                    value: opacity2
-                },
-                
-                uColor: {
-                    value: color
-                },
-                uDistance: {
-                    value: distance
-                }
-            },
-            transparent: true,
-            vertexShader: `
-               
-               varying vec3 worldPosition;
-               
-               uniform float uDistance;
-               
-               void main() {
-               
-                    vec3 pos = position.xyz * uDistance;
-                    pos.xy += cameraPosition.xy;
-                    
-                    worldPosition = pos;
-                    
-                    gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.0);
-               
-               }
-               `,
-
-
-            fragmentShader: `
-               
-               varying vec3 worldPosition;
-               
-               uniform float uSize1;
-               uniform float uSize2;
-               uniform float opacity1;
-               uniform float opacity2;
-               uniform vec3 uColor;
-               uniform float uDistance;
-                
-                
-                
-                float getGrid(float size) {
-                
-                    vec2 r = worldPosition.xy / size;
-                    
-                    
-                    vec2 grid = abs(fract(r - 0.5) - 0.5) / fwidth(r);
-                    float line = min(grid.x, grid.y);
-                    
-                
-                    return 1.0 - min(line, 1.0);
-                }
-                //为何侧面看不到线,因为mesh的正侧面都看不到?
-
-               void main() {
-               
-                    
-                      float d = 1.0 - min(distance(cameraPosition.xy, worldPosition.xy) / uDistance, 1.0);
-                    
-                      float g1 = getGrid(uSize1);
-                      float g2 = getGrid(uSize2);
-                      
-                      
-                      gl_FragColor = vec4(uColor.rgb, mix(g2, g1, g1) * pow(d, 3.0));
-                      //gl_FragColor.a = mix(0.5 * gl_FragColor.a, gl_FragColor.a, g2);
-                        gl_FragColor.a = mix(opacity1 * gl_FragColor.a, opacity2 * gl_FragColor.a, g2);
-                        
-                        
-                      if ( gl_FragColor.a <= 0.0 ) discard;
-                    
-               
-               }
-               
-               `,
-
-            extensions: {
-                derivatives: true
-            }
-            
-            
-            
-        })
-        
-        
-        super(geometry, material)
-        this.frustumCulled = false;
-
-    }
-
-
-    
-
-    
-
-};
-
-
-
-export default InfiniteGridHelper
-/* 
-THREE.InfiniteGridHelper.prototype = {
-    ...THREE.Mesh.prototype,
-    ...THREE.Object3D.prototype,
-    ...THREE.EventDispatcher.prototype
-};
- */

+ 0 - 84
src/objects/Label.js

@@ -1,84 +0,0 @@
-import * as THREE from "../../libs/three.js/build/three.module.js";
-import {Utils} from "../utils.js";  
-import {ExtendEventDispatcher} from "../custom/ExtendEventDispatcher.js";
-
-
-class Label  extends ExtendEventDispatcher{
-    constructor(o={}){
-        super()
-        
-        this.position = o.pos;
-        this.text = o.text || '';
-        this.elem = $('<div class="hide"><a></a></div>');
-        o.className && this.elem.addClass(o.className)
-        this.elem.find('a').html(this.text); 
-        $("#potree_labels").append(this.elem)
-        this.pos2d = new THREE.Vector3
-        this.dom = o.dom || viewer.renderArea
-        this.camera = o.camera || viewer.scene.getActiveCamera() 
-        
-        
-        let update = (e)=>{
-            this.update(e) 
-        }
-        viewer.addEventListener('camera_changed',  update)
-           
-         
-        this.addEventListener('dispose', ()=>{
-            viewer.removeEventListener('camera_changed',  update)
-            this.dispose()
-            
-        })
-        
-    }
-     
-    update(){
-        if(!this.position || this.elem.hasClass('unvisible'))return
-        var p = Utils.getPos2d(this.position,this.camera,this.dom, viewer.mainViewport);
-        if(!p.trueSide){
-            this.elem.addClass("hide");  return;
-        }
-        this.elem.css({
-            left: p.pos.x +'px',
-            top: p.pos.y +'px'
-        })
-        
-        
-        
-        this.elem.removeClass("hide");
-        this.pos2d = p.vector;
-        
-        
-        
-        
-        
-    }
-    
-    setVisible(visi){
-        if(!visi){
-            this.elem.addClass("unvisible");  
-        }else{
-            this.elem.removeClass("unvisible");
-            this.update()
-        }
-    }
-    
-    setText(text){
-        this.text = text || '';
-        this.elem.find('a').html(this.text); 
-    }
-    setPos(pos){
-        this.position = pos;
-    }
-    
-    dispose(){
-        this.elem.remove();
-        this.removeAllListeners()
-    }
-     
-     
-}
-
-export default Label;
-
-

+ 0 - 350
src/objects/Magnifier.js

@@ -1,350 +0,0 @@
-
-import * as THREE from "../../libs/three.js/build/three.module.js";
-import math from '../utils/math.js'
-import browser from '../utils/browser.js'
-import Viewport from '../viewer/Viewport.js'
- 
-const texLoader = new THREE.TextureLoader() 
-const circleGeo = new THREE.CircleGeometry(1.45,100);
-const sphereGeo = new THREE.SphereBufferGeometry(0.018,10,10);
- 
- 
-const magDistance_ = 1;//相机离目标位置的距离的分界线,当离得远时要缩小fov以使看到的视野固定(望远镜效果)
-/* const radius_ = 0.2; //当相机离目标位置的距离>magDistance_时,希望看到的视野的半径
-const maxFov = THREE.Math.radToDeg(Math.atan(radius_ / magDistance_ )) * 2//提前计算出当相机离目标位置的距离<magDistance_时的fov,均使用=magDistance_时的fov。只要保证该fov大于主相机的fov就会有放大效果 
- */
-let w = 200/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)
-
-
-
-export default class Magnifier extends THREE.Object3D {//放大镜or望远镜
-	constructor (viewer) {
-		super()
-        this.width = this.height = width2dPX/*  * window.devicePixelRatio */;
-        this.camera = new THREE.PerspectiveCamera(50, 1, 0.01, 10000);  //fov aspect near far
-        this.camera.up = new THREE.Vector3(0,0,1) 
-        
-        
-        this.viewport = new Viewport( null, this.camera, {
-            left:0, bottom:0, width:1, height: 1, name:'magnifier' , cameraLayers:['magnifierContent'],
-            pixelRatio:1
-        })
-        this.viewport.setResolution(this.width, this.height,0,0)
-        
-        { 
-            let density
-            let sizeType
-            let colorType
-            let opacityBefore = new Map()
-            this.viewport.beforeRender = ()=>{
-                viewer.scene.pointclouds.forEach(e=>{//因为更改pointDensity时会自动变opacity,所以这项最先获取
-                    opacityBefore.set(e,e.temp.pointOpacity)  
-                }) 
-                
-                
-                //使放大镜里的pointDensity是'magnifier'  最高质量。
-                density = Potree.settings.pointDensity 
-                Potree.settings.pointDensity = 'magnifier' 
-                 
-                viewer.scene.pointclouds.forEach(e=>{//因为全景模式的pointSizeType是fixed所以要还原下
-                    sizeType = e.material.pointSizeType  
-                    e.material.pointSizeType = Potree.config.material.pointSizeType  
-                     
-                    //材质
-                    colorType = e.material.activeAttributeName
-                    e.material.activeAttributeName = 'rgba'
-                    e.changePointOpacity(1) 
-                   
-                }) 
-            };
-            
-            
-            this.viewport.afterRender = ()=>{
-                Potree.settings.pointDensity = density
-                
-                viewer.scene.pointclouds.forEach(e=>{
-                    e.material.pointSizeType = sizeType
-                    e.material.activeAttributeName = colorType  
-                    e.changePointOpacity(opacityBefore.get(e))  
-                }) 
-            } 
-        }
-        
-        
-        
-        
-        this.renderTarget = new THREE.WebGLRenderTarget(this.width,this.height, { 
-            minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter,
-            format: THREE.RGBAFormat ,
-            /* type: THREE.FloatType,
-            minFilter: THREE.NearestFilter,
-			magFilter: THREE.NearestFilter, 
-			  */ 
-        } )
-        
-		this.rtEDL = new THREE.WebGLRenderTarget(this.width, this.height, {  //好像没用到? 因为这里不绘制测量线
-			minFilter: THREE.NearestFilter,
-			magFilter: THREE.NearestFilter,
-			format: THREE.RGBAFormat,
-			type: THREE.FloatType,
-			depthTexture: new THREE.DepthTexture(undefined, undefined, THREE.UnsignedIntType)
-		});
-        
-        
-        
-        this.mesh = new THREE.Mesh(circleGeo, new THREE.MeshBasicMaterial({
-            side: THREE.DoubleSide , 
-            map: this.renderTarget.texture ,
-            transparent:true,
-            depthTest: !1,
-            //depthWrite: !1,
-        }))
-        this.overlayMesh = new THREE.Mesh(circleGeo, new THREE.MeshBasicMaterial({
-            side: THREE.DoubleSide , 
-            map:texLoader.load(Potree.resourcePath+'/textures/crosshair.png') ,
-            transparent:true,
-            depthTest: !1,
-            //depthWrite: !1,
-        }))
-        this.targetPoint = new THREE.Object3D;
-        
-        this.targetPoint.add(new THREE.Mesh(sphereGeo, new THREE.MeshBasicMaterial({ 
-            color:"#ff0000",
-            transparent:true,
-            opacity:0.5,  
-        })))
-        this.targetPoint.add(new THREE.Mesh(sphereGeo, new THREE.MeshBasicMaterial({ 
-            color:"#ff0000",
-            transparent:true,
-            opacity:0.2, 
-            depthTest:false  //被遮挡层
-        })))
-        
-        this.targetPoint.name = 'magnifierPointTarget'
-        viewer.scene.scene.add(this.targetPoint)
-        viewer.setObjectLayers(this.targetPoint, 'magnifierContent' )
-        
-        this.add(this.mesh)
-        this.add(this.overlayMesh)
-        
-        this.position.set(-1000,-1000,-100000)//令它看不见
-        this.mesh.renderOrder = 10;
-        this.overlayMesh.renderOrder = 11;
-        this.aimPos
-        viewer.setObjectLayers(this, 'magnifier' )
-        //viewer.inputHandler.addInputListener(this)
-        
-        
-        
-        
-        viewer.addEventListener('camera_changed',(e)=>{ // 平移、滚轮时更新
-            if(e.viewport == viewer.mainViewport) this.update() //不过intersectPoint没更新 
-        }) 
-            
-         
-        
-        
-        this.mesh.layers.set(Potree.config.renderLayers.magnifier);
-        this.overlayMesh.layers.set(Potree.config.renderLayers.magnifier);
-        //this.layers.set(Potree.config.renderLayers.magnifier);//这句在外层写没用
-        
-        this.dontRender = false 
-        viewer.addEventListener('global_drag', (e)=>{//拖拽时不渲染。主要是右键平移时渲染延迟了,会闪烁。 
-            this.dontRender = true 
-        })
-        viewer.addEventListener('global_drop', (e)=>{
-            this.dontRender = false
-        })
-        viewer.addEventListener('global_mouseup', (e)=>{//测量时拖拽场景再mouseup
-            this.dontRender = false
-        })
-        
-        var updateVisi = (e)=>{
-            if(e.hoverViewport == viewer.mainViewport){
-                viewer.updateVisible(this,"atViewport", true)
-                this.update(e.intersect && e.intersect.location)
-            }else{
-                viewer.updateVisible(this,"atViewport", false) //小地图不显示
-            } 
-            
-        }
-        
-        viewer.addEventListener('global_mousemove', updateVisi)
-        viewer.addEventListener('global_touchstart', updateVisi)
-        
-        
-        /* viewer.addEventListener("beginSplitView",()=>{
-            this.updateVisible("splitView", false) 
-        })
-        viewer.addEventListener("finishSplitView",()=>{
-            this.updateVisible("splitView", true) 
-        })  */
-         
-         
-        this.addEventListener("setEnable",(e)=>{
-            viewer.updateVisible(this, "enable", e.value) //界面开关
-            /* if(Potree.settings.displayMode == 'showPanos') && e.value){
-                Potree.settings.pointDensity = 'magnifier'
-            }else if() */
-            
-        })
-         
-         
-        if(Potree.settings.isOfficial){
-            viewer.updateVisible(this, "enable", false) 
-        }else{
-            viewer.updateVisible(this, "measure", false) 
-            viewer.addEventListener("measureMovePoint",()=>{//测量开始
-                viewer.updateVisible(this, "measure", true) 
-            })
-            viewer.addEventListener("endMeasureMove",()=>{
-                viewer.updateVisible(this, "measure", false) 
-            })
-        }
-        
-        
-        viewer.scene.view.addEventListener('flyingDone',()=>{
-            if(!this.visible)return
-            let pickWindowSize = 100
-            let intersect = viewer.inputHandler.getIntersect(viewer.mainViewport, viewer.mainViewport.camera, true, pickWindowSize )
-            this.update(intersect && intersect.location)
-        })
-    }
-    
-    
-   
-    
-    //注意:在鼠标没有移动的时候,无法获取到最新的intersect, 放大镜内的内容可能是错误的。全景模式下更奇怪,原因未知
-    update(aimPos){//相机靠近 navvis的做法 
-        var dontRender = this.dontRender || !(aimPos instanceof THREE.Vector3) || Potree.settings.displayMode == 'showPanos' && viewer.images360.flying
-        aimPos = aimPos instanceof THREE.Vector3 ?  aimPos : this.aimPos
-        if(!aimPos  || !this.visible)return
-        
-        
-        
-        var playerCamera = viewer.scene.getActiveCamera()
-        var playerPos = playerCamera.position;//viewer.scene.view.getPivot()
-        var dis = playerPos.distanceTo(aimPos);
-        var dirToCamera = new THREE.Vector3().subVectors(playerPos, aimPos ).normalize()
-        
-        
-        //相机位置
-        var finalDisToAim = dis>magDistance_ ? magDistance_ : dis / 2;
-        this.camera.position.copy(aimPos).add(dirToCamera.multiplyScalar(finalDisToAim))
-        this.camera.lookAt(aimPos)
-        this.camera.fov = playerCamera.fov / 2
-        this.camera.updateProjectionMatrix()
-        
-        
-
-         
-        //自身位置 
-        //let pos2d = viewer.inputHandler.pointer.clone();   //跟随鼠标 
-        let pos2d = Potree.Utils.getPos2d(aimPos, playerCamera, viewer.renderArea, viewer.mainViewport).vector   //更新目标点的实时二维位置
-        let margin = 0.4, maxY = 0.4
-        let screenPos = pos2d.clone().setY(pos2d.y + (pos2d.y>maxY ? -margin : margin ))
-        
-        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_  ;
-        
-        this.position.copy(playerPos.clone().add(dir))
-        this.quaternion.copy(playerCamera.quaternion); 
-        this.targetPoint.position.copy(aimPos); 
-        this.targetPoint.scale.set(s,s,s)
-        this.aimPos = aimPos
-       
-        
-        var scale = math.getScaleForConstantSize({// 
-            width2d : width2dPX,
-            camera:viewer.scene.getActiveCamera(),  position: this.getWorldPosition(new THREE.Vector3()),
-            resolution: viewer.mainViewport.resolution2 
-        })
-        this.scale.set(scale, scale, scale); 
- 
-        if(!dontRender){
-            this.waitRender = true
-        } 
-    
-    }
-    
-    
-    /* update(aimPos){  //仅改fov的版本
-        
-        aimPos = aimPos instanceof THREE.Vector3 ?  aimPos : this.aimPos
-        if(!aimPos  || !this.visible)return
-        
-    
-        //相机位置
-        var playerCamera = viewer.scene.getActiveCamera()
-        var playerPos = playerCamera.position;//viewer.scene.view.getPivot()
-        var dis = playerPos.distanceTo(aimPos);
-         
-        
-        if(dis<magDistance_){
-            this.camera.fov = maxFov
-        }else{
-            this.camera.fov = THREE.Math.radToDeg(Math.atan(radius_ / dis )) * 2 //radius_是能看到的范围半径。当dis大于magDistance_时就放大,否则维持fov为maxFov
-        }
-       
-        this.camera.updateProjectionMatrix()
-        this.camera.position.copy(playerPos)
-        this.camera.lookAt(aimPos)
-        
-        this.quaternion.copy(playerCamera.quaternion);
-  
-        let pointer = viewer.inputHandler.pointer.clone();
-        let margin = 0.4, maxY = 0.4
-        let screenPos = pointer.clone().setY(pointer.y + (pointer.y>maxY ? -margin : margin ))
-       
-                
-        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
-        
-        this.position.copy(playerPos.clone().add(dir))
-          
-        this.aimPos = aimPos
-        this.targetPoint.position.copy(aimPos);
-        
-        var scale = math.getScaleForConstantSize({// 
-            width2d : width2dPX,
-            camera:viewer.scene.getActiveCamera(),  position: this.getWorldPosition(new THREE.Vector3()),
-            resolution: viewer.mainViewport.resolution2 
-        })
-        this.scale.set(scale, scale, scale); 
- 
-        if(!this.dontRender){
-            this.waitRender = true
-        }   
-    }//位置需要计算,不仅仅是点云,所以需要深度图
-     */
-    
-    
-    
-    
-    
-    render(){ 
- 
-        if(!this.waitRender)return
-        //this.visible = false;//防止放大镜里有自己
-        viewer.render({
-            target : this.renderTarget,
-            viewports : [this.viewport],
-            camera : this.camera,
-            magnifier : true,
-            rtEDL: this.rtEDL 
-            /* width :this.renderTarget.width,
-            height: this.renderTarget.height, */
-        })
-        //this.visible = true;
-        this.waitRender = false
-        
-        
-        
-        
-    }
-   
-}

+ 0 - 271
src/objects/Reticule.js

@@ -1,271 +0,0 @@
-import * as THREE from "../../libs/three.js/build/three.module.js";
-import {Buttons} from '../defines.js'
-import {transitions, easing, lerp} from '../utils/transitions.js'
-import math from '../utils/math.js'
-
-
-let texLoader = new THREE.TextureLoader()
-let defaultOpacity =  0.7
- 
-
-
-//鼠标指示小圆片 
-export default class Reticule extends THREE.Mesh{
-    constructor(viewer){
-        var defaultTex = texLoader.load(Potree.resourcePath+'/textures/whiteCircle.png'/* reticule-256x256.png'  */)  
-        super(new THREE.PlaneBufferGeometry(0.11,0.11,1,1),new THREE.MeshBasicMaterial({
-            side: THREE.DoubleSide , 
-            map: defaultTex,
-            transparent:true,
-            depthTest: !1,
-            opacity: defaultOpacity,
-            //depthWrite: !1,
-        })) 
-        this.name = 'reticule'
-        this.defaultTex = defaultTex
-        this.crosshairTex = texLoader.load(Potree.resourcePath+'/textures/reticule_cross_hair.png') 
-        this.forbitTex = texLoader.load(Potree.resourcePath+'/textures/pic-forbid.png') 
-        
-        //this.layers.set(0/* RenderLayers.RETICULE */);
-        this.renderOrder = 100
-        this.layers.set(Potree.config.renderLayers.marker);
-        
-        
-        this.direction = new THREE.Vector3;
-       
-        this.mouseLastMoveTime = Date.now();
-        this.hoverViewport;
-        this.matrixMap = new Map 
-        this.matrixAutoUpdate = false 
-        
-
-        this.hide(0)
-
-        //viewer.inputHandler.addInputListener(this);
-        Potree.settings.intersectWhenHover && viewer.addEventListener('global_mousemove',this.move.bind(this))
-        //viewer.addEventListener('global_click',this.move.bind(this))
-        viewer.addEventListener('global_mousedown',this.move.bind(this))//主要针对触屏
-        
-        
-        
-        
-        this.state = {}
-        
-        let startCrossStyle = ()=>{
-            this.state.cross = true
-            this.judgeTex()
-        }
-        let endCrossStyle = ()=>{
-            this.state.cross = false
-            this.judgeTex()
-        }
-        
-        viewer.addEventListener('measureMovePoint',startCrossStyle) 
-        viewer.addEventListener('endMeasureMove',endCrossStyle)
-        viewer.addEventListener('start_inserting_tag',startCrossStyle) 
-        viewer.addEventListener('endTagMove',endCrossStyle)
-        
-        viewer.addEventListener('reticule_forbit',(e)=>{
-            if(this.state.forbit != e.v){
-                console.log('change forbit ',e.v)
-            }
-            this.state.forbit = e.v
-            this.judgeTex() 
-        })
-        
-         
-        
-        viewer.setObjectLayers(this, 'sceneObjects' )
-    }
-
-    judgeTex(){ 
-        if(this.state.forbit){
-            this.material.map = this.forbitTex 
-        }else if(this.state.cross){
-            this.material.map = this.crosshairTex 
-        }else{
-            this.material.map = this.defaultTex 
-        }
-        
-         
-        viewer.mapViewer && viewer.mapViewer.dispatchEvent({type:'content_changed'})
-    }
-
-
-
-
-    move(e){ 
-        if(e.type == "global_mousemove" && (e.isTouch || e.buttons != Buttons.NONE) && this.state != 'crosshair'){
-            return//按下时不更新,除非拖拽测量
-        }
-           
-        this.mouseLastMoveTime = Date.now()
-        
-        this.updatePosition(e.intersect, e.hoverViewport)
-         
-    }
-
-    hide(duration = 500){ 
-        if(this.hidden)return
-        
- 
-        
-        this.hidden = !0 
-        transitions.start(lerp.property(this.material , "opacity", 0), duration)
-             
-        this.dispatchEvent({type:'update', visible:false})
-        
-        setTimeout(()=>{
-            this.dispatchEvent({type:'update', visible:false})
-        },duration)
-        
-    }
-
-    show(duration = 300){
-         
-        if(!viewer.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)
-        
-            this.dispatchEvent({type:'update', visible:true})
-            
-            setTimeout(()=>{
-                this.dispatchEvent({type:'update', visible:false})
-            },duration)
-                
-        }
-        
-        
-        
-    }
-
-    //鼠标静止一段时间它就会消失
-    updateVisible(){
-        Date.now() - this.mouseLastMoveTime > 1500 && !this.hidden && this.hide()
-    }
-    
-    
-    updateScale(viewport){
-        let s, camera = viewport.camera
-        if(camera.type == "OrthographicCamera"){
-            
-            var sizeInfo = this.state.cross ? {width2d:500} : {minSize : 100,  maxSize : 400,   nearBound : 100 , farBound :  700}
-            s = math.getScaleForConstantSize($.extend(   sizeInfo ,  
-            {position:this.position, camera, resolution:viewport.resolution/* 2 */} ))
-            
-        }else{
-            
-            let n = camera.position.distanceTo(this.position)
-            s = 1 + .1 * n;
-            n < 1 && (s -= 1 - n)
-        }
-        this.scale.set(s, s, s);
-        
-    }
-
-    updateAtViewports(viewport){//当多个viewports时更新。更新大小等
-    
-        if(viewport.name == 'magnifier' )return
-    
-        if(this.hoverViewport && this.hoverViewport.name == 'mapViewport' && viewport != this.hoverViewport){
-            //若是在地图上更新,在其他viewport要隐藏。因为在地图上无法得知高度。     
-            viewer.updateVisible(this, 'hoverMap', false)
-            return; 
-        }
-        viewer.updateVisible(this, 'hoverMap', true)   
-    
-        var matrix = this.matrixMap.get(viewport)
-        if(!matrix){ 
-            this.updateScale(viewport)
-            this.updateMatrix(); 
-            //this.updateMatrixWorld()
-            this.matrixMap.set(viewport, this.matrix.clone())
-        }else{
-            this.matrix.copy(matrix) 
-            //this.updateMatrixWorld()
-        }
-        
-    }
-   
-    
-    
-
-    
-
-    updatePosition(intersect, viewport ){ //在地图(当地图融合到viewer时)和场景里都显示且完全相同(大小可能不同)
-         
-        if (viewer.getObjVisiByReason(this, 'force')) {//没有被强制隐藏,如进入某个页面后强制不显示
-            if (!intersect /* || !intersect.point.normal */){ 
-                 return //this.hide();   
-            }
-                
-            var atMap = !intersect.location
-            let location = intersect.location || intersect.orthoIntersect.clone()
-            let normal  
-            
-            
-            //地图上要瞬间变化 , 因为要使needRender为true很麻烦
-            this.show(atMap ? 0 : 300);
-            
-            
-            if(atMap){ 
-                normal =  new THREE.Vector3(0,0,1)//地图无normal
-                location.setZ(0);//低于相机高度即可
-                this.direction = normal.clone()
-            }else{
-                /* if(intersect.point){ 
-                    if(intersect.pointcloud){
-                        normal = new THREE.Vector3().fromArray(intersect.point.normal ).applyMatrix4( intersect.pointcloud.rotateMatrix  );
-                    }else{//mesh 
-                        normal = new THREE.Vector3().copy(intersect.point.normal).applyQuaternion(intersect.object.quaternion) 
-                    } 
-                }else{
-                    normal = intersect.normal  //when showPanos
-                } */
-                normal = intersect.normal 
-                if(normal){
-                    let ratio = /* Potree.settings.useDepthTex ? 1 : */ 0.2;   
-                    this.direction = this.direction.multiplyScalar(1-ratio); 
-                    this.direction.add(normal.clone().multiplyScalar(ratio)); 
-                }
-                //this.direction = normal.clone() //改为瞬间变化,否则刚hover上某个点时看起来不太对
-            }
-             
-             
-            
-            
-            this.position.copy(location)/* .add(normal.clone().multiplyScalar(.01));  */
-            this.updateMatrix();  //lookAt之前要保证得到matrix
-            this.lookAt(this.position.clone().add(this.direction));
-            
-            
-            this.hoverViewport = viewport //记录下最近一次hover过的viewport  
-            this.updateScale(viewport)
-            
-            
-            {//存储matrix,节省计算
-                this.updateMatrix(); 
-                //this.updateMatrixWorld()
-                this.matrixMap.clear();//重新计算
-                this.matrixMap.set(viewport, this.matrix.clone())
-                //别处会updateMatrixWorld
-            }
-            
-            this.dispatchEvent({type:'update'})
-            
-            //为什么navvis在校准数据集时每个viewport里reticule的朝向都刚好垂直于屏幕,似乎限定在了一定范围内,还是在pick时就只pick范围内的点?
-            
-            
-        }
-    }
-    
-    //navvis在地图等地方看reticule是有厚度的
-    
-    /* updateMatrixWorld(force){
-        console.log('updateMatrixWorld', force)
-        super.updateMatrixWorld(force) 
-    } */
-}

+ 0 - 166
src/objects/Sprite.js

@@ -1,166 +0,0 @@
-import * as THREE from "../../libs/three.js/build/three.module.js";
-import DepthBasicMaterial from "../materials/DepthBasicMaterial.js";
-import math from "../utils/math.js";
-
-const geo = new THREE.PlaneBufferGeometry(1,1)
-export default class Sprite extends THREE.Mesh{
-    
-    constructor(options){  
-        super(geo, options.mat || new DepthBasicMaterial({map:options.map, useDepth:options.useDepth}))
-         
-        this.root = options.root || this;
-        this.renderOrder = options.renderOrder != void 0 ? options.renderOrder : 4;
-        this.pickOrder = options.pickOrder || 0
-        this.sizeInfo = options.sizeInfo
-        this.dontFixOrient = options.dontFixOrient
-        
-        this.root.matrixAutoUpdate = false;
-        this.matrixMap = new Map()
-        this.name = options.name || 'sprite'
-        this.useViewport = null
-        this.viewports = options.viewports//指定更新的viewports
-        this.visible_ = true
-        
-        
-        let update = (e)=>{
-            this.update(e) 
-        }
-        viewer.mapViewer && viewer.mapViewer.addEventListener("camera_changed",  update) 
-        viewer.addEventListener("camera_changed",  update) 
-        /* if(viewer.viewports.length == 1){//直接更新。如果有多个不在这更新,在"render.begin"
-            this.update(e)
-        } */
-         
-        
-        let applyMatrix = (e)=>{
-            this.applyMatrix(e)
-        }
-        viewer.addEventListener("raycaster", applyMatrix)        //before render
-        viewer.addEventListener("render.begin", applyMatrix) //before render  //magnifier时要禁止吗
-            
-        this.addEventListener('dispose', ()=>{
-            viewer.mapViewer && viewer.mapViewer.removeEventListener("camera_changed",  update) 
-            viewer.removeEventListener("camera_changed",  update) 
-            viewer.removeEventListener("raycaster", applyMatrix)        //before render
-            viewer.removeEventListener("render.begin", applyMatrix)
-             
-            this.dispose()
-        })
-         
-    }
-    
-    set visible(v){
-        this.visible_ = v  
-        if(v){
-            this.update()
-        }
-    }
-    get visible(){
-        return this.visible_ 
-    }
-    
-    realVisible(){
-        let parent = this
-        
-        let v
-        while(parent){
-            if(parent.visible === false){
-                v = false
-                break; 
-            }
-            parent = parent.parent
-        }
-        v = true;
-        if(!this.latestRealVisi && v){//变为可见后先update 
-            this.latestRealVisi = true
-            setTimeout(()=>{
-                this.update()
-            },1)//延迟 防止无限调用
-            return false
-        }
-        
-        this.latestRealVisi = v
-        return v;
-    }
-    
-    update(e){
-        if(!e){
-            (this.viewports || viewer.viewports).forEach(view=>{
-                this.update({viewport:view}) 
-            })
-            return;
-        }
-        if(!this.root || ! this.realVisible() /* this.visible */ )return
-        if(this.viewports && !this.viewports.includes(e.viewport) )return
-        if(e.viewport.name == 'magnifier')return
-        
-        let camera = e.viewport.camera
-        //rotation
-        this.dontFixOrient || this.root.quaternion.copy(camera.quaternion)
-        
-        //scale
-        var info = this.sizeInfo
-        if(info){
-            this.root.updateMatrix();//先更新,getWorldPosition才能得到正确的
-            this.root.updateMatrixWorld(true)
-            
-            
-            var scale
-            if(info.restricMeshScale){//仅限制最大或最小的话,不判断像素大小,直接限制mesh的scale
-                var dis = camera.position.distanceTo(this.root.getWorldPosition(new THREE.Vector3()))
-                if(dis < info.nearBound){
-                    scale = info.scale * dis / info.nearBound
-                }else{
-                    scale = info.scale
-                }
-            }else{ 
-                scale = math.getScaleForConstantSize($.extend(info,{//规定下最小最大像素 
-                    camera , position:this.root.getWorldPosition(new THREE.Vector3()) ,
-                    resolution: e.viewport.resolution//2
-                }))
-                
-            } 
-            
-            if(!isNaN(scale)){
-                this.root.scale.set(scale, scale, scale); 
-            } 
-        }
-        this.root.updateMatrix();
-        this.root.updateMatrixWorld(true)
-        this.matrixMap.set(e.viewport, this.root.matrix.clone())
-        
-        this.useViewport = e.viewport
-    }
-    
-    applyMatrix(e){
-        if(!e)e = {viewport:viewer.mainViewport}//随便写一个viewport
-        if(e.viewport.name == 'magnifier')return
-        if(this.viewports && !this.viewports.includes(e.viewport) )return
-        if( !this.root || !this.realVisible()  )return
-        
-        var matrix = this.matrixMap.get(e.viewport);
-          
-        if(!matrix){
-            this.update(e)
-            matrix = this.matrixMap.get(e.viewport);
-        }
-        
-        if(e.viewport == this.useViewport){
-            return
-        }       
-        this.useViewport = e.viewport   
-        this.root.matrix.copy(matrix) 
-        this.root.updateMatrixWorld(true)
-        //console.log(this.root.name + e.viewport.name + " : "+this.root.matrixWorld.elements)
-    }
-    
-    setUniforms(name,value){
-        this.material.setUniforms(name,value) 
-    }
-    
-     
-    dispose(){
-        this.removeAllListeners()
-        this.parent && this.parent.remove(this)
-    }
-}

+ 0 - 161
src/objects/Tag.js

@@ -1,161 +0,0 @@
-
-
-
-import * as THREE from "../../libs/three.js/build/three.module.js"; 
-
-import {LineDraw, MeshDraw} from "../utils/DrawUtil.js";  
-import {TextSprite} from './TextSprite.js' 
-import Sprite from './Sprite.js' 
-
-const renderOrders = {
-    line: 0 ,
-    spot: 15, //高过模型
-}
-const planeGeo = new THREE.PlaneGeometry(1,1)
-let texLoader = new THREE.TextureLoader() 
-
-let lineMat = new THREE.LineBasicMaterial({
-    color: '#ffffff', 
-})
-let spotMat 
-const defaultLineLength = 0.6
-const defaultSpotScale = 0.4
-
-class Tag extends THREE.Object3D{
-    constructor(o){
-        
-        super()
-        
-         
-        this.lineLength = o.lineLength != void 0 ? o.lineLength : defaultLineLength
-        this.position.copy(o.position)
-        this.normal = o.normal != void 0 ? o.normal : new THREE.Vector3(0,0,-1)
-        this.root = o.root
-        
-        
-        //this.matrixAutoUpdate = false
-        
-        this.build()
-        
-        /* this.spot.addEventListener('mouseover',()=>{
-            
-             
-        }) */
-        
-    }
-    
-    
-    
-    
-    build(){
-        
-        if(!spotMat){
-            spotMat = new THREE.MeshBasicMaterial({
-                transparent:true,
-                map: texLoader.load(Potree.resourcePath+'/textures/spot_default.png' ),  
-            })
-        }
-        let endPos = this.normal.clone().multiplyScalar(this.lineLength) 
-        
-  
-        this.line = LineDraw.createLine([
-            new THREE.Vector3(0,0,0), 
-            endPos
-        ],  {mat:lineMat})
-        
-        
-        let group = new THREE.Object3D()
-        this.spot = new THREE.Mesh(planeGeo, spotMat)  
-        this.spot.scale.set(defaultSpotScale,defaultSpotScale,defaultSpotScale) 
-        this.titleLabel = new TextSprite({root: group, text:'1', sizeInfo:{width2d:200}, 
-            textColor:{r:255,g:255,b:255,a:1.0},
-            backgroundColor:{r:0,g:0,b:0,a:0.8},
-            borderRadius: 6,  
-            fontsize:13,  fontWeight:'',//thick
-            renderOrder : renderOrders.spot, pickOrder:renderOrders.spot,
-        }) //更新sprite时,实际更新的是root: spot的矩阵
-        this.spot.renderOrder = renderOrders.spot;
-        /* const mainLabelProp = { 
-            backgroundColor: {r: defaultColor.r*255, g: defaultColor.g*255, b: defaultColor.b*255, a:config.measure.default.opacity},
-            textColor: {r: textColor.r*255, g: textColor.g*255, b: textColor.b*255, a: 1.0},
-            fontsize:16, 
-            useDepth : true ,
-            renderOrder : 5, pickOrder:5, 
-        } */
-            
-        this.titleLabel.position.set(0,0.4,0)
-        this.titleLabel.sprite.material.depthTest = this.titleLabel.sprite.material.depthWrite = true
-        
-        
-        group.position.copy(endPos)
-        group.add(this.spot)
-        group.add(this.titleLabel)
-        this.add(group);
-        this.add(this.line)
-        
-        
-        
-        
-        viewer.scene.tags.add(this)
-        
-        
-    }
-    
-    
-    changeTitle(title){
-        this.titleLabel.changeText(title)
-    }
-    
-    
-    updateMatrixWorld(force){ //重写,只为了将root当做parent
-         
-        this.updateMatrix() 
-        this.matrixWorld.multiplyMatrices( this.root.matrixWorld, this.matrix );
-         
-        const children = this.children;
-        for ( let i = 0, l = children.length; i < l; i ++ ) {
-            children[ i ].updateMatrixWorld( force );
-        }  
-    }
-    
-
-    updateWorldMatrix( updateParents, updateChildren ) {//重写,只为了将root当做parent
- 
-        if ( updateParents === true && this.root !== null ) {
-            this.root.updateWorldMatrix( true, false );
-        }
-
-        if ( this.matrixAutoUpdate ) this.updateMatrix();
-        this.matrixWorld.multiplyMatrices( this.root.matrixWorld, this.matrix );
-
-        if ( updateChildren === true ) {
-            const children = this.children;
-            for ( let i = 0, l = children.length; i < l; i ++ ) {
-                children[ i ].updateWorldMatrix( false, true );
-            }
-        }
-
-    } 
-
-    
-    dispose(){
-        this.parent.remove(this);
-        this.titleLabel.dispatchEvent({type:'dispose'})
-        
-    } 
-    
-    
-    
-}
-
-
-
-
-export default Tag
-
-
-
-
-
-
-

+ 0 - 177
src/objects/TextSprite.js

@@ -1,177 +0,0 @@
-
-
-// /**
-//  * adapted from http://stemkoski.github.io/Three.js/Sprite-Text-Labels.html
-//  */
-
-import * as THREE from "../../libs/three.js/build/three.module.js";
-import Sprite from './Sprite.js' 
-
-
-//可能还是要用html写,因为要加按钮和图片
-
-export class TextSprite extends THREE.Object3D{ 
-    //注:为了分两层控制scale,不直接extend Sprite
-	constructor( options={}){ 
-        super()
-		let map = new THREE.Texture();
-		map.minFilter = THREE.LinearFilter;
-		map.magFilter = THREE.LinearFilter;
-        
-        this.sprite = new Sprite( Object.assign({
-                root:this
-            }
-            ,options,
-            { 
-                map,
-            })
-        )
-        this.add(this.sprite)
-        
-        this.fontWeight = options.fontWeight == void 0 ? 'Bold' : options.fontWeight
-		this.rectBorderThick = options.rectBorderThick || 0
-		this.textBorderThick = options.textBorderThick || 0
-		this.fontface = 'Arial';
-		this.fontsize = options.fontsize ||  16; 
-        this.textBorderColor = options.textBorderColor || { r: 0, g: 0, b: 0, a: 0.0 };
-		this.backgroundColor = options.backgroundColor || { r: 255, g: 255, b: 255, a: 1.0 };
-		this.textColor = options.textColor || {r: 0, g: 0, b: 0, a: 1.0};
-        this.borderColor = options.borderColor || { r: 0, g: 0, b: 0, a: 0.0 };
-		this.borderRadius = options.borderRadius || 6;
-        if(options.text != void 0)this.setText(options.text)
-        this.name = options.name 
-         
-		//this.setText(text);
-        
-        
-        this.addEventListener('dispose', this.dispose.bind(this)) 
-	}
-
-	setText(text){
-		if (this.text !== text){
-			this.text = text + '';
-
-			this.updateTexture();
-		}
-	}
-
-	setTextColor(color){
-		this.textColor = color;
-
-		this.updateTexture();
-	}
-
-	setBorderColor(color){
-		this.borderColor = color;
-
-		this.updateTexture();
-	}
-
-	setBackgroundColor(color){
-		this.backgroundColor = color;
-
-		this.updateTexture();
-	}
-    setPos(pos){
-        this.position.copy(pos)
-        this.sprite.update()
-    }
-    update(){
-        this.sprite.update()
-    }
-    setVisible(v){
-        this.visible = v
-    }
-    setUniforms(name,value){
-        this.sprite.setUniforms(name,value)
-    }
-	updateTexture(){
-		let canvas = document.createElement('canvas');
-		let context = canvas.getContext('2d');
-		context.font = this.fontWeight + ' ' + this.fontsize + 'px ' + this.fontface; 
-       
-        //context["font-weight"] = 100; //语法与 CSS font 属性相同。
-		// get size data (height depends only on font size)
-        
-        //this.text = '啊啊啊啊啊啊fag'
-        
-		let metrics = context.measureText(this.text );
-		let textWidth = metrics.width;
-		let margin = new THREE.Vector2(this.fontsize, Math.max(  this.fontsize*0.4, 10)  );
-		let spriteWidth = 2 * margin.x + textWidth + 2 * this.rectBorderThick;
-		let spriteHeight = 2 * margin.y + this.fontsize + 2 * this.rectBorderThick; 
-		context.canvas.width = spriteWidth;
-		context.canvas.height = spriteHeight;
-		context.font = this.fontWeight + ' ' + this.fontsize + 'px ' + this.fontface; 
-
-         
-        let diff = 2//针对英文大部分在baseLine之上所以降低一点(metrics.fontBoundingBoxAscent - metrics.fontBoundingBoxDescent) / 2
-
-        context.textBaseline = "middle"
-        
-        // border color
-        context.strokeStyle = 'rgba(' + this.borderColor.r + ',' + this.borderColor.g + ',' +
-            this.borderColor.b + ',' + this.borderColor.a + ')';
-  
-        context.lineWidth = this.rectBorderThick;
-		// background color
-		context.fillStyle = 'rgba(' + this.backgroundColor.r + ',' + this.backgroundColor.g + ',' +
-			this.backgroundColor.b + ',' + this.backgroundColor.a + ')';
-        this.roundRect(context, this.rectBorderThick / 2, this.rectBorderThick / 2,
-            spriteWidth - this.rectBorderThick, spriteHeight - this.rectBorderThick, this.borderRadius);
-        
-		// text color
-        if(this.textBorderThick){
-            context.strokeStyle = 'rgba(' + this.textBorderColor.r + ',' + this.textBorderColor.g + ',' +
-                this.textBorderColor.b + ',' + this.textBorderColor.a + ')';
-            context.lineWidth = this.textBorderThick;
-            context.strokeText(this.text , this.rectBorderThick + margin.x,spriteHeight/2  + diff );
-        }
-        
-		context.fillStyle = 'rgba(' + this.textColor.r + ',' + this.textColor.g + ',' +
-			this.textColor.b + ',' + this.textColor.a + ')';
-		context.fillText(this.text , this.rectBorderThick + margin.x, spriteHeight/2  + diff );//x,y
-
-		let texture = new THREE.Texture(canvas);
-		texture.minFilter = THREE.LinearFilter;
-		texture.magFilter = THREE.LinearFilter;
-		texture.needsUpdate = true;
-		//this.material.needsUpdate = true; 
-        
-        if(this.sprite.material.map){
-            this.sprite.material.map.dispose()
-        }
-		this.sprite.material.map = texture;
-		 
-        
-        
-		this.sprite.scale.set(spriteWidth * 0.01, spriteHeight * 0.01, 1.0);
-	}
-
-	roundRect(ctx, x, y, w, h, r){
-		ctx.beginPath();
-		ctx.moveTo(x + r, y);
-		ctx.lineTo(x + w - r, y);
-        ctx.arcTo(x + w, y, x + w, y + r, r );//圆弧。前四个参数同quadraticCurveTo
-		//ctx.quadraticCurveTo(x + w, y, x + w, y + r); //二次贝塞尔曲线需要两个点。第一个点是用于二次贝塞尔计算中的控制点,第二个点是曲线的结束点。
-		ctx.lineTo(x + w, y + h - r);
-		ctx.arcTo(x + w, y + h, x + w - r, y + h, r );
-		ctx.lineTo(x + r, y + h);
-		ctx.arcTo(x, y + h, x, y + h - r, r );
-		ctx.lineTo(x, y + r);
-		ctx.arcTo(x, y, x + r, y, r );
-		ctx.closePath();
-		ctx.fill();
-		ctx.stroke();
-	}
-    
-    dispose(){
-        this.sprite.material.uniforms.map.value.dispose()
-        this.parent && this.parent.remove(this)
-        this.sprite.dispatchEvent({type:'dispose'})
-        this.removeAllListeners()
-    }
-
-}
-
-

+ 0 - 36
src/objects/fireParticle/Tween.js

@@ -1,36 +0,0 @@
-import * as THREE from "../../../libs/three.js/build/three.module.js";
-import Common  from "../../utils/Common.js";
-
-
-
-class Tween {
-
-    constructor(times, values) {
-      this.times = times || []
-      this.values = values || []
-    }
-  
-    lerp(t) {
-      if(this.times.length == 0) return
-      let i = 0, n = this.times.length
-      while(i < n && t > this.times[i]) i++
-      if(i == 0) return this.values[0]
-      if(i == n) return this.values[n-1]
-      const ratio = (t - this.times[i-1]) / (this.times[i] - this.times[i-1])
-      if(this.values[0] instanceof THREE.Vector3) {
-        return this.values[i-1].clone().lerp(this.values[i], ratio)
-      } else {
-        return this.values[i-1] + ratio * (this.values[i] - this.values[i-1])
-      }
-      
-    }
-    
-    
-    clone () {
-        return Common.CloneClassObject(this)
-	}
-    
-  
-  }
-  
-  export default Tween

+ 0 - 475
src/objects/fireParticle/explode/ExplodeParticle.js

@@ -1,475 +0,0 @@
-import*as THREE from "../../../../libs/three.js/build/three.module.js";
-import {vertexShader, fragmentShader} from './shader.js'
-import Tween from '../Tween.js'
-import Particle from './Particle.js'
-import {util} from './Util.js'
-import {Shape} from './const.js'
-
-let particleTexture
-
-const getTexture = ()=>{
-    if (!particleTexture) {
-        particleTexture = new THREE.TextureLoader().load(Potree.resourcePath + '/textures/explode.png')
-    }
-    return particleTexture
-}
-const sphereGeo = new THREE.SphereBufferGeometry(1, 10,4);
-const sphereMat = new THREE.MeshBasicMaterial({wireframe:true, color:"#ffffff"})
-
-const defaults = {
-    position: new THREE.Vector3(0,0,1),
-
-    positionShape: Shape.SPHERE,
-
-    positionRange: new THREE.Vector3(1,1,1),
-    //cube
-
-    radius: 1.3,
-    //sphere
-
-    velocityShape: Shape.SPHERE,
-
-    velocity: new THREE.Vector3(0,0,2),
-    //cube
-    velocityRange: new THREE.Vector3(0,0,3),
-    
-    //sphere
-    speed: 0.4, 
-    speedRange: 1,
-
-    size: 0.4,
-    sizeRange: 2,
-    //sizeTween: new Tween( [0, 0.05, 0.3, 0.45], [0, 1, 3, 0.1] ),
-    sizeTween: [[0, 0.04, 0.2, 1],[0.1, 1, 6, 8]] ,
-
-    color: new THREE.Vector3(1.0,1.0,1.0),
-    colorRange: new THREE.Vector3(0,0,0),
-    colorTween: new Tween(),
-
-    opacity: 1.0,
-    opacityRange: 0.0,
-    opacityTween: new Tween([0, 0.06, 0.3, 0.8, 1],[0, 1, 0.3, 0.05, 0]),
-    blendMode: THREE.AdditiveBlending,
-
-    acceleration: 0.5,
-    accelerationRange: 0,
-
-    angle: 0,
-    angleRange: 0,
-    angleVelocity: 0,
-    angleVelocityRange: 0,
-    angleAcceleration: 0,
-    angleAccelerationRange: 0,
-    
-    strength:1,
-    
-    //particlesPerSecond: 8,
-    particleDeathAge: 0.7 , 
-    recycleTimes : 3 , //每个粒子在一次爆炸后循环次数,循环完毕进入particleSpaceTime,等待下一次爆炸.
-    //爆炸时长: particleDeathAge * (recycleTimes+1)
-    particleSpaceTime:   3, //间隔
-    
-    
-}
-
-class ExplodeParticle extends THREE.Points {
-
-    constructor(params) {
-        super()
-         
-
-        this.age = 0
-        this.alive = true
-        //this.deathAge = 60
-        this.loop = true
-
-        this.blendMode = THREE.NormalBlending
-
-        this.setParameters(params)
-        this.createParticles()
-        this.frustumCulled = false//似乎是禁止相机裁剪,否则会在某些角度消失。但是会不会更耗性能呢?
-        //------------------------------------
-
-        this.setSize({viewport:viewer.mainViewport})
-        this.setFov(viewer.fov)
-        
-        let setSize = (e)=>{
-            if(e.viewport.name != "MainView")return
-            this.setSize(e)
-        }
-        let setFov = (e)=>{
-            this.setFov(e.fov) 
-        }
-            
-        /* let reStart = (e)=>{
-            if(e.v){//重新一个个放出粒子,否则会一股脑儿全部出来,因为同时大于粒子周期了一起重新生成出现。
-                setTimeout(()=>{//会先update一次delta为pageUnvisile的时间才触发 
-                    //console.log('归零') 
-                    //this.reStart()
-                },1) 
-            } 
-        } */
-        viewer.addEventListener('resize',setSize) 
-        viewer.addEventListener('fov_changed',setFov)
-        //viewer.addEventListener('pageVisible', reStart)
-        
-        this.addEventListener('dispose',()=>{
-            viewer.removeEventListener('resize',setSize) 
-            viewer.removeEventListener('fov_changed',setFov)
-            //viewer.removeEventListener('pageVisible', reStart)
-        })  
- 
-        
-    }
-    
-    
-    computeParams(){
-        if(this.curve){
-            this.position.copy(this.curve.points[0])
-        }
-         
-         
-         
-        const minSize = 0.8, maxSize = 10, minRadiusBound = 0.2, maxRadiusBound = 20;
-        let size = minSize + (maxSize - minSize) * THREE.Math.smoothstep(this.radius*this.strength , minRadiusBound, maxRadiusBound);
-        
-        this.sizeTween.values = this.defaultSizeTween.values.map(e=> e*size)
-        
-        this.particleCount = Math.ceil( this.strength  * this.radius * 5 /*  * this.radius  * this.radius */  )
-     
-        this.speed = defaults.speed * this.radius;
-        this.speedRange = defaults.speedRange * this.radius;
-     
-        console.log(this.particleCount)
-        
-        {
-            this.boundPoints = []
-            this.boundPoints.push(this.position.clone())    
-            let maxSize = this.sizeTween.values.slice().sort((a,b)=>b-a)[0]  
-            let margin = maxSize * 0.35 + 0.5;  
-            let scale = this.radius+margin
-            let sphere = new THREE.Sphere(this.position, scale)//加上防止剪裁
-            this.boundingSphere = sphere //虽然还是会有一些后续移动的会超出 
-            this.boundingBox = new THREE.Box3().setFromCenterAndSize(this.position, new THREE.Vector3(scale*2,scale*2,scale*2)) 
-            /* if(!this.debugSphere){
-                this.debugSphere = new THREE.Mesh(sphereGeo, sphereMat)
-                this.add(this.debugSphere)
-            } 
-            this.debugSphere.scale.set(scale,scale,scale)  */
-        }
-    }
-    getPointsForBound(){
-        return this.boundPoints; //可以用于expand实时bound的点, 不含particle的size等边距
-    }   
-
-    reStart(){
-        this.age = 0;
-        
-        this.createParticles()  
-    }
-
-
-    setParameters(params) {
-        
-        params = $.extend({}, defaults, params)
-         
-         
-        for (var key in params) { 
-            let value = params[key] 
-            if (key == 'position')
-                this.position.copy(value)
-            else if (value instanceof Array && value[0]instanceof Array){
-                this[key] = new Tween(...value)
-            }else if(value instanceof THREE.Vector3 || value instanceof THREE.Color){
-                this[ key ] = value.clone()
-            }else{
-                this[key] = value;
-            }
-        }
-        
-        
-        this.defaultSizeTween = this.sizeTween.clone()
-        //Object.assign(this, params) 
-
-        this.particles = []
-        this.age = 0.0
-        this.alive = true
-        
-        this.geometry = new THREE.BufferGeometry() 
-        this.computeParams() 
-        this.material = new THREE.ShaderMaterial({
-            uniforms: {
-                u_sampler: {
-                    value: this.texture || getTexture()
-                },
-                heightOfNearPlane: {
-                    type: "f",
-                    value: 0
-                }//相对far ,以确保画面缩放时点的大小也会缩放
-            },
-            vertexShader,
-            fragmentShader,
-            transparent: true,
-            alphaTest: 0.5,
-            depthTest: this.blendMode == THREE.NormalBlending,
-            blending: this.blendMode
-        })
-         
-         
-    }
-
-
-    createParticles() {
-        this.particles = []
-        const count = this.particleCount
-        const positionArray = new Float32Array(count * 3)
-        const colorArray = new Float32Array(count * 3)
-
-        const sizeArray = new Float32Array(count)
-        const angleArray = new Float32Array(count)
-        const opacityArray = new Float32Array(count)
-        const visibleArray = new Float32Array(count)
-
-        for (let i = 0; i < count; i++) {
-            const particle = this.createParticle()
-            /* positionArray[i * 3] = particle.position.x
-            positionArray[i * 3 + 1] = particle.position.y
-            positionArray[i * 3 + 2] = particle.position.z
-            colorArray[i * 3] = particle.color.r
-            colorArray[i * 3 + 1] = particle.color.g
-            colorArray[i * 3 + 2] = particle.color.b
-            sizeArray[i] = particle.size
-            angleArray[i] = particle.angel
-            opacityArray[i] = particle.opacity
-            visibleArray[i] = particle.alive */
-            this.particles[i] = particle
-        }
-        this.geometry.setAttribute('position', new THREE.BufferAttribute(positionArray,3))
-        this.geometry.setAttribute('color', new THREE.BufferAttribute(colorArray,3))
-        this.geometry.setAttribute('angle', new THREE.BufferAttribute(angleArray,1))
-        this.geometry.setAttribute('size', new THREE.BufferAttribute(sizeArray,1))
-        this.geometry.setAttribute('visible', new THREE.BufferAttribute(visibleArray,1))
-        this.geometry.setAttribute('opacity', new THREE.BufferAttribute(opacityArray,1))
-
-        
-
-    }
-    
-    
-    
-     
-
-    createParticle() {
-
-        const particle = new Particle()
-        particle.sizeTween = this.sizeTween
-        particle.colorTween = this.colorTween
-        particle.opacityTween = this.opacityTween
-        particle.deathAge = this.particleDeathAge
-
-        if (this.positionShape == Shape.CUBE) {
-            particle.position = util.randomVector3(new THREE.Vector3, this.positionRange)
-        }
-
-        if (this.positionShape == Shape.SPHERE) {
-            /* const z = 2 * Math.random() - 1
-              const t = Math.PI * 2 * Math.random()
-              const r = Math.sqrt(1 - z*z)
-              const vec3 = new THREE.Vector3(r * Math.cos(t), r * Math.sin(t), z)
-              particle.position = vec3.multiplyScalar(this.radius)  */
-
-            const y = 2 * Math.random() - 1
-            const t = Math.PI * 2 * Math.random();
-            const r = Math.sqrt(1 - y * y);
-            const vec3 = new THREE.Vector3(r * Math.cos(t),y,r * Math.sin(t));
-            particle.position = vec3.multiplyScalar(this.radius)
-
-        }
-
-        if (this.velocityShape == Shape.CUBE) {
-            particle.velocity = util.randomVector3(this.velocity, this.velocityRange)
-
-        }
-
-        if (this.velocityShape == Shape.SPHERE) {
-            const direction = new THREE.Vector3().addVectors(particle.position, new THREE.Vector3(0,0,this.radius*2))//向上升?
-            const speed = util.randomValue(this.speed, this.speedRange)
-            particle.velocity = direction.normalize().multiplyScalar(speed)
-        }
-
-        particle.acceleration = util.randomValue(this.acceleration, this.accelerationRange)
-
-        particle.angle = util.randomValue(this.angle, this.angleRange)
-        particle.angleVelocity = util.randomValue(this.angleVelocity, this.angleVelocityRange)
-        particle.angleAcceleration = util.randomValue(this.angleAcceleration, this.angleAccelerationRange)
-
-        particle.size = util.randomValue(this.size, this.sizeRange)
-
-        const color = util.randomVector3(this.color, this.colorRange)
-        particle.color = new THREE.Color().setHSL(color.x, color.y, color.z)
-
-        particle.opacity = util.randomValue(this.opacity, this.opacityRange)
-     
-
-        return particle
-    }
-
-    update(dt) {
-        if(!viewer.getObjVisiByReason(this,'force')){//被手动隐藏了
-            return
-        }
-        if(this.delayStartTime>0){ // 爆炸延迟
-            return this.delayStartTime -= dt 
-        }
-        
-        
-        
-        if(!Potree.Utils.isInsideFrustum(this.boundingSphere, viewer.scene.getActiveCamera())){
-            viewer.updateVisible(this,'isInsideFrustum', false ) //不在视野范围
-            return
-        }else{
-            viewer.updateVisible(this,'isInsideFrustum', true )
-        }
-        //const timeRatio = 0.5
-        if(dt > 1){
-            console.log('update dt>1', dt)
-        }
-        //dt *= timeRatio
-        let particleDeathAge = this.particleDeathAge/*  * timeRatio */
-        let particleSpaceTime = this.particleSpaceTime /* * timeRatio */
-
-        const recycleIndices = []
-        const recycleAges = []
-        const recycleRebornCount = []
-        
-        const positionArray = this.geometry.attributes.position.array
-        const opacityArray = this.geometry.attributes.opacity.array
-        const visibleArray = this.geometry.attributes.visible.array
-        const colorArray = this.geometry.attributes.color.array
-        const angleArray = this.geometry.attributes.angle.array
-        const sizeArray = this.geometry.attributes.size.array
-
-        for (let i = 0; i < this.particleCount; i++) {
-            const particle = this.particles[i]
-            if (particle.alive) {
-                particle.update(dt)
-                if (particle.age > particleDeathAge) { 
-                    particle.alive = 0.0
-                    if(particle.rebornCount >= this.recycleTimes){
-                        particle.deadAge = particle.age - particleDeathAge //已死亡时间
-                    }else{//直接循环
-                        recycleIndices.push(i)
-                        recycleAges.push(/* ( */particle.age - particleDeathAge/* )%(this.particleDeathAge ) */)
-                        recycleRebornCount.push(particle.rebornCount+1)
-                    }
-                    
-                }
-                positionArray[i * 3] = particle.position.x
-                positionArray[i * 3 + 1] = particle.position.y
-                positionArray[i * 3 + 2] = particle.position.z
-                colorArray[i * 3] = particle.color.r
-                colorArray[i * 3 + 1] = particle.color.g
-                colorArray[i * 3 + 2] = particle.color.b
-                visibleArray[i] = particle.alive
-                opacityArray[i] = particle.opacity
-                angleArray[i] = particle.angle
-                sizeArray[i] = particle.size
-            }else{
-                if(particle.rebornCount >= this.recycleTimes){
-                    if(particle.age > particleDeathAge) {//其他已经死亡的粒子的时间继续增加
-                        particle.deadAge += dt
-                    }
-                }
-            }                
-                
-             
-            
-            if (particle.rebornCount >= this.recycleTimes && particle.age > particleDeathAge) {//已经死亡 
-                if(particle.deadAge >=  particleSpaceTime){//死亡时间超过设定的间隔时间后重启 
-                    recycleIndices.push(i)
-                    let wholeTime = particleDeathAge * (this.recycleTimes+1) + particleSpaceTime 
-                    recycleAges.push((particle.deadAge - particleSpaceTime)% wholeTime ) //剩余时间就是重生后的age
-                    recycleRebornCount.push(0)
-                } 
-            }
-            
-        }
-        
-        
-        
-
-        this.geometry.attributes.size.needsUpdate = true
-        this.geometry.attributes.color.needsUpdate = true
-        this.geometry.attributes.angle.needsUpdate = true
-        this.geometry.attributes.visible.needsUpdate = true
-        this.geometry.attributes.opacity.needsUpdate = true
-        this.geometry.attributes.position.needsUpdate = true
-
-        if (!this.alive)
-            return
-
-        if (this.age < particleDeathAge) {
-            let startIndex = Math.round(this.particleCount * (this.age + 0)/ particleDeathAge)
-            let endIndex = Math.round(this.particleCount * (this.age + dt)/ particleDeathAge)
-            if (endIndex > this.particleCount) {
-                endIndex = this.particleCount
-            }
-            for (let i = startIndex; i < endIndex; i++) {
-                this.particles[i].alive = 1.0
-            }
-        }
-
-
-
-        for (let j = 0; j < recycleIndices.length; j++) {
-            let i = recycleIndices[j]
-            
-            this.particles[i] = this.createParticle()
-            this.particles[i].alive = 1.0  //出生
-            this.particles[i].age = recycleAges[j]  
-            this.particles[i].rebornCount= recycleRebornCount[j]
-            /* if(this.particles[i].age < particleDeathAge){
-                positionArray[i * 3] = this.particles[i].position.x
-                positionArray[i * 3 + 1] = this.particles[i].position.y
-                positionArray[i * 3 + 2] = this.particles[i].position.z
-                visibleArray[i] = particle.alive?
-            } */
-        }
-        this.geometry.attributes.position.needsUpdate = true
-
-        this.age += dt
-
-        if (this.age > this.deathAge && !this.loop) {
-            this.alive = false
-        }
-
-    }
-
-    setSize(e) {
-        let viewport = e.viewport
-        this.screenHeight = viewport.resolution.y
-        this.setPerspective(this.fov, this.screenHeight)
-    }
-
-    setFov(fov) {
-        this.fov = fov
-        this.setPerspective(this.fov, this.screenHeight)
-    }
-
-    setPerspective(fov, height) {
-        //this.uniforms.heightOfNearPlane.value = Math.abs(height / (2 * Math.tan(THREE.Math.degToRad(fov * 0.5))));
-        let far = Math.abs(height / (2 * Math.tan(THREE.Math.degToRad(fov * 0.5))));
-        this.material.uniforms.heightOfNearPlane.value = far
-    }
-    updateGeometry(){ 
-        this.computeParams()
-        this.reStart()  
-    }
-    dispose(){
-        this.geometry.dispose();
-        this.material.dispose();
-        this.dispatchEvent('dispose') 
-    }
-}
-
-export default ExplodeParticle

+ 0 - 57
src/objects/fireParticle/explode/Particle.js

@@ -1,57 +0,0 @@
-// import { vertexShader, fragmentShader } from './shader'
-// import Tween from './tween'
-import * as THREE from "../../../../libs/three.js/build/three.module.js";
-
-const DEG2RAD = Math.PI / 180
-
-class Particle {
-  
-  constructor() {
-    
-    this.position = new THREE.Vector3()
-    this.velocity = new THREE.Vector3()
-     
-    
-    this.angle = 0
-    this.angleVelocity = 0
-    this.angleAcceleration = 0
-    this.size = 16
-    this.color = new THREE.Color()
-    this.opacity = 1
-
-    this.rebornCount = 0//重生次数
-    this.age = 0
-    this.alive = 0 //注意,一开始时是未出生的
-    this.deadAge = 0//已死亡时间
-    this.sizeTween = null
-    this.colorTween = null
-    this.opacityTween = null
-  }
-
-  update(dt) { 
-    //s = s0 + (v0 + at) * t 或 lastS + delta(vt)
-    
-    this.position.add(this.velocity.clone().multiplyScalar(dt))
-    this.velocity.multiplyScalar( 1+this.acceleration*dt )
-    
-    this.angle += this.angleVelocity * DEG2RAD * dt
-    this.angleVelocity += this.angleAcceleration * DEG2RAD * dt
-    this.age += dt
-
-    if(this.sizeTween.times.length > 0) {
-      this.size = this.sizeTween.lerp(this.age/this.deathAge)
-    }
-
-    if(this.colorTween.times.length > 0) {
-      const colorHSL = this.colorTween.lerp(this.age/this.deathAge)
-      this.color = new THREE.Color().setHSL(colorHSL.x, colorHSL.y, colorHSL.z)
-    }
-
-    if(this.opacityTween.times.length > 0) {
-      this.opacity = this.opacityTween.lerp(this.age/this.deathAge)
-    }
-  }
-
-}
-
-export default Particle

+ 0 - 18
src/objects/fireParticle/explode/Util.js

@@ -1,18 +0,0 @@
-import * as THREE from "../../../../libs/three.js/build/three.module.js";
-export class Util {
-    constructor() {}
-
-    randomValue(min, max) {
-        //return min + max * (Math.random() - 0.5)
-        let p = Math.random()
-        return min * p + max * (1-p)
-    }
-
-    randomVector3(min, max) {
-        const rand3 = new THREE.Vector3(Math.random() - 0.5, Math.random() - 0.5, Math.random() - 0.5)
-        return new THREE.Vector3().addVectors(min, new THREE.Vector3().multiplyVectors(max, rand3))
-    }
-}
-
-const util = new Util();
-export { util };

+ 0 - 4
src/objects/fireParticle/explode/const.js

@@ -1,4 +0,0 @@
-export const Shape = {
-    CUBE: 1,
-    SPHERE: 2
-  }

+ 0 - 40
src/objects/fireParticle/explode/shader.js

@@ -1,40 +0,0 @@
-export const vertexShader = `
-  attribute vec3 color;
-  attribute float size;
-  attribute float angle;
-  attribute float opacity;
-  attribute float visible;
-  varying vec4 vColor;
-  varying float vAngle;
-  uniform float heightOfNearPlane;
-  
-  void main() {
-    if(visible > 0.5) {
-      vColor = vec4(color, opacity);
-    } else {
-      vColor = vec4(0.0, 0.0, 0.0, 0.0);
-    }
-    vAngle = angle;
-    vec4 mvPosition = modelViewMatrix * vec4(position, 1.0);
-    gl_Position = projectionMatrix * mvPosition;
-    
-    gl_PointSize = ( heightOfNearPlane * size ) / gl_Position.w;
-  }
-` 
-
-export const fragmentShader = `
-  uniform sampler2D u_sampler;
-  varying vec4 vColor;
-  varying float vAngle;
-  void main() {
-    gl_FragColor = vColor;
-    float u = cos(vAngle);
-    float v = sin(vAngle);
-    vec2 uv = vec2(
-      u * (gl_PointCoord.x - 0.5) + v * (gl_PointCoord.y - 0.5) + 0.5, 
-      u * (gl_PointCoord.y - 0.5) - v * (gl_PointCoord.x - 0.5) + 0.5
-    );
-    vec4 texture = texture2D(u_sampler, uv);
-    gl_FragColor = gl_FragColor * texture;
-  }
-`

+ 0 - 274
src/objects/fireParticle/fire/FireParticle.js

@@ -1,274 +0,0 @@
-// import { vertexShader, fragmentShader } from './shaders'
-// import Tween from './tween'
-import * as THREE from "../../../../libs/three.js/build/three.module.js";
-import { vertexShader, fragmentShader } from './shader.js'
-
-let ONE_SPRITE_ROW_LENGTH = 0.25    //对应着色器的0.25
-let texture 
- 
-
-const getTexture = ()=>{
-    if(!texture){
-        texture = new THREE.TextureLoader().load( Potree.resourcePath+'/textures/fire.png')
-    }
-    return texture
-}
-
-const boxGeo = new THREE.BoxBufferGeometry(1,1,1,1);
-const boxMat = new THREE.MeshBasicMaterial({wireframe:true, color:"#ffffff"})
-
-
-
-class FireParticle extends THREE.Points{
-  
-    constructor (prop) {
-        super()
-        
-        for ( var key in prop ){
-            this[key] = prop[key]
-        }
-        
-        
-         
-        this.strength = this.strength || 1
-        
-        
-         
-        this.radius = prop.radius || 1;
-        this.height = prop.height || 5;  
-        
-        this.computeParams()
-        this.geometry = this.createGeometry( this.radius, this.height, this.particleCount );
-         
-        
-        if(this.color == void 0)   this.color = 0xff3200
-        this.createMaterial( );  //小蓝火:0x00338f
-        
-      
-         
-        //---?:
-        this.velocity = new THREE.Vector3()
-        this.acceleration = new THREE.Vector3()
-        
-        this.angle = 0
-        this.angleVelocity = 0
-        this.angleAcceleration = 0
-        this.size = 16
-        
-        this.opacity = 1
-
-        this.age = 0
-        this.alive = 0
-
-        this.sizeTween = null
-        this.colorTween = null
-        this.opacityTween = null
-
-        
-         
-        this.setSize({viewport:viewer.mainViewport})
-        this.setFov(viewer.fov)
-        
-        let setSize = (e)=>{
-            if(e.viewport.name != "MainView")return
-            this.setSize(e)
-        }
-        let setFov = (e)=>{
-            this.setFov(e.fov) 
-        }
-            
-        viewer.addEventListener('resize',setSize) 
-        viewer.addEventListener('fov_changed',setFov)
-          
-        this.addEventListener('dispose',()=>{
-            viewer.removeEventListener('resize',setSize) 
-            viewer.removeEventListener('fov_changed',setFov)
-        })  
-          
-    }
-
- 
-    computeParams(){  
-        let length = (this.curve ? this.curve.wholeLength : 0) + this.radius * 2 //加上首尾的半径
-        
-        
-        const minSize = 0.3, maxSize = 3, minRadiusBound = 0.3, maxRadiusBound = 10;
-        this.size = minSize + (maxSize - minSize) * THREE.Math.smoothstep(this.radius, minRadiusBound, maxRadiusBound);
-        //console.log('fire material  particle size:', size )
-        
-        this.particleCount =  Math.ceil(   length * Math.sqrt(this.strength  * this.height )   * this.radius / (this.size * this.size) *  25  )        
-        //console.log('fire particleCount',this.particleCount)
-    }
-    getPointsForBound(){
-        return this.boundPoints; //可以用于expand实时bound的点, 不含particle的size等边距
-    }
-
-    getBound(points){ // points为生成点(圆心)
-        this.boundPoints = []  
-        let boundingBox = new THREE.Box3()
-        
-         
-        let margin = this.size * 0.13 + 0.3; 
-        
-        points.forEach(bottom=>{ 
-            let top = bottom.clone()
-            top.z +=  this.height 
-            boundingBox.expandByPoint(bottom);
-            boundingBox.expandByPoint(top);
-            this.boundPoints.push(bottom,top)            
-        })
-        let xyExpand = this.radius+margin 
-        boundingBox.expandByVector(new THREE.Vector3(xyExpand,xyExpand,margin)) 
-        this.boundingBox = boundingBox
-        
-        /* if(!this.debugBox){
-            this.debugBox = new THREE.Mesh(boxGeo, boxMat)
-            this.add(this.debugBox)
-        }
-        
-        this.debugBox.scale.copy(boundingBox.getSize(new THREE.Vector3))
-        this.debugBox.position.copy(boundingBox.getCenter(new THREE.Vector3))  */
-         
-    }
-
-
-    createGeometry( radius, height, particleCount){
-        let geometry = new THREE.BufferGeometry()
-         
-        
-        let count , points
-        if(this.positions.length>1){
-             
-            const spaceDis = 0.2;//间隔距离
-            
-            count = Math.ceil(this.curve.wholeLength / spaceDis) + 1 
-            //console.log('count', count)
-            points = this.curve.getSpacedPoints( count );  //得到的数量会比count多一个
-            count = points.length  
-            //得到的点不太均匀,两端容易点少。
-            this.getBound(points) 
-            
-        }else{
-            this.getBound(this.positions) 
-        }
-         
-        
-        var position = new Float32Array(particleCount * 3);
-        var randam = new Float32Array(particleCount);
-        var sprite = new Float32Array(particleCount);
-        var centerHeight = new Float32Array(particleCount);
-        
-        for (var i = 0; i < particleCount; i++) {
-            
-            var center = new THREE.Vector3().copy(this.positions.length>1 ? points[Math.floor(i/particleCount * count)] : this.positions[0])
-            centerHeight[i] = center.z
-            
-            if (i === 0) { 
-                // to avoid going out of Frustum
-                position[i * 3 + 0] = center.x;
-                position[i * 3 + 1] = center.y;
-                position[i * 3 + 2] = center.z;
-            }else{  
-                var r = Math.sqrt(Math.random()) * radius;
-                var angle = Math.random() * 2 * Math.PI;
-                position[i * 3 + 0] = center.x + Math.cos(angle) * r; 
-                position[i * 3 + 1] = center.y + Math.sin(angle) * r;
-                position[i * 3 + 2] = center.z + (radius - r) / radius * height/2 + height/2; //不太明白这句为什么能达到height高度
-               
-                sprite[i] = 0.25 * (Math.random() * 4 | 0);
-                randam[i] = Math.random();
-                //center在底部
-            }
-            
-            
-        }
-        
-        geometry.setAttribute('centerHeight', new THREE.BufferAttribute(centerHeight, 1));
-        geometry.setAttribute('position', new THREE.BufferAttribute(position, 3));
-        geometry.setAttribute('randam', new THREE.BufferAttribute(randam, 1));
-        geometry.setAttribute('sprite', new THREE.BufferAttribute(sprite, 1));
-        return geometry;
-    }
-    
-    
-    
-    
-    updateGeometry(){ 
-        this.computeParams()
-        this.geometry.dispose() 
-        this.geometry = this.createGeometry( this.radius, this.height, this.particleCount )
-        this.material.uniforms.size.value = this.size
-    }
-
-
-
-
-    createMaterial(){
-         
-        
-        const material = new THREE.ShaderMaterial( {
-            uniforms:{
-                color: { type: "c", value: new THREE.Color(this.color) },
-                size: { type: "f", value: this.size},
-                u_sampler: { type: "t", value: getTexture() },
-                time: { type: "f", value: 0.0 },
-                heightOfNearPlane: { type: "f", value:0},  //相对far ,以确保画面缩放时点的大小也会缩放
-                height :{ type: "f", value:this.height}  ,
-            },
-            vertexShader,
-            fragmentShader,
-            blending: THREE.AdditiveBlending, //加法融合模式 glBlendFunc(GL_ONE, GL_ONE)
-            depthTest: true,
-            depthWrite: false,
-            transparent: true
-
-        } ); 
-        this.material = material
-        this.setPerspective(this.fov, this.screenHeight)
-    }
-
-
-    setSize(e){
-        let viewport = e.viewport
-        this.screenHeight = viewport.resolution.y
-        this.setPerspective(this.fov, this.screenHeight)  
-    }
-    
-    setFov(fov){
-        this.fov = fov
-        this.setPerspective(this.fov, this.screenHeight) 
-    }
-    
-    
-    setPerspective(fov, height){
-        //this.uniforms.heightOfNearPlane.value = Math.abs(height / (2 * Math.tan(THREE.Math.degToRad(fov * 0.5))));
-        let far = Math.abs(height / (2 * Math.tan(THREE.Math.degToRad(fov * 0.5))));
-        this.material.uniforms.heightOfNearPlane.value = far 
-    }
-
-    
-    
-    update(delta){
-        if(!viewer.getObjVisiByReason(this,'force')){//被手动隐藏了
-            return
-        }
-        if(!Potree.Utils.isInsideFrustum(this.boundingBox, viewer.scene.getActiveCamera())){
-            viewer.updateVisible(this,'isInsideFrustum', false ) //不在视野范围
-            //console.log('unvi')
-            return
-        }else{
-            viewer.updateVisible(this,'isInsideFrustum', true )
-        } 
-        delta *= 1//更改速度
-        
-        this.material.uniforms.time.value = (this.material.uniforms.time.value + delta) % 1; 
-    }
-    
-    dispose(){
-        this.geometry.dispose();
-        this.material.dispose();
-        this.dispatchEvent('dispose') 
-    }
-}
-
-export default FireParticle

+ 0 - 63
src/objects/fireParticle/fire/shader.js

@@ -1,63 +0,0 @@
-export const vertexShader = `
-    attribute float randam;
-    attribute float sprite;
-    attribute float centerHeight;  //add
-    
-    //uniform float fireHeight;  //add 
-    uniform float time;
-    uniform float size;
-    uniform float heightOfNearPlane;
-    
-    
-    
-    
-    //varying float heightRatio;
-    varying float vSprite;
-    varying float vOpacity; 
-    float PI = 3.14;
-
-    float quadraticIn( float t ) 
-    { 
-        float tt = t * t;
-        return tt * tt; 
-        //变化曲线  越来越快
-    } 
-    
-    void main() {
-        float progress = fract( time + ( 2.0 * randam - 1.0 ) );
-        float progressNeg = 1.0 - progress;
-        float ease = quadraticIn( progress );
-        float influence = sin( PI * ease );
-        //vec3 newPosition = position * vec3( 1.0,  1.0 , ease);
-        vec3 newPosition = position;
-        newPosition.z = (newPosition.z - centerHeight) * ease + centerHeight;
-         
-        gl_Position = projectionMatrix * modelViewMatrix * vec4( newPosition, 1.0 );
-        gl_PointSize = ( heightOfNearPlane * size ) / gl_Position.w;
-        vOpacity = min( influence * 4.0, 1.0 ) * progressNeg;
-        vSprite = sprite;
-        
-        //heightRatio = (newPosition.z - centerHeight) / fireHeight ;
-        
-    }
-` 
-
-export const fragmentShader = `
-    uniform vec3 color;
-    uniform sampler2D u_sampler;
-
-    varying float vSprite;
-    varying float vOpacity;
-    //varying float heightRatio;
-
-    void main() 
-    {
-        
-       
-        vec2 texCoord = vec2(gl_PointCoord.x * 0.25 + vSprite, gl_PointCoord.y);
-         
-        gl_FragColor = vec4( texture2D( u_sampler, texCoord ).xyz * color * vOpacity, 1.0 );
-          
-         
-    }
-`

+ 0 - 57
src/objects/fireParticle/smoke/Particle.js

@@ -1,57 +0,0 @@
-import * as THREE from "../../../../libs/three.js/build/three.module.js";
-import Tween from '../Tween.js'
-export default class Particle{
-    constructor(prop={}){
-        this.position     = new THREE.Vector3();
-        this.velocity     = new THREE.Vector3(); // units per second
-         
-        this.angle             = 0;
-        this.angleVelocity     = 0; // degrees per second
-        this.angleAcceleration = 0; // degrees per second, per second
-        this.size = 16.0;
-    
-        this.color   = new THREE.Color();
-        this.opacity = 1.0;
-                
-        this.age   = 0;
-        this.alive = 0; // use float instead of boolean for shader purposes	
-        this.lastChangeVage = 0 //add
-
-
-        this.sizeTween    = prop.sizeTween || new Tween( [0, 1], [32, 128] );
-		this.opacityTween = prop.opacityTween || new Tween( [0.8, 2], [0.5, 0] );
-		this.colorTween   = prop.colorTween || new Tween( [0.4, 1], [ new THREE.Vector3(0,0,0.2), new THREE.Vector3(0, 0, 0.5) ] );
-   
-   
-   
-   }
-
-    update(dt)
-    {
-        this.position.add(this.velocity.clone().multiplyScalar(dt))
-        this.velocity.multiplyScalar( 1+this.acceleration*dt )
-        
-        // convert from degrees to radians: 0.01745329251 = Math.PI/180
-        this.angle         += this.angleVelocity     * 0.01745329251 * dt;
-        this.angleVelocity += this.angleAcceleration * 0.01745329251 * dt;
-
-        this.age += dt;
-        
-        // if the tween for a given attribute is nonempty,
-        //  then use it to update the attribute's value
-
-        if ( this.sizeTween.times.length > 0 )
-            this.size = this.sizeTween.lerp( this.age/this.deathAge );
-                    
-        if ( this.colorTween.times.length > 0 )
-        {
-            var colorHSL = this.colorTween.lerp( this.age/this.deathAge );
-            this.color = new THREE.Color().setHSL( colorHSL.x, colorHSL.y, colorHSL.z );
-        }
-        
-        if ( this.opacityTween.times.length > 0 )
-        {
-            this.opacity = this.opacityTween.lerp( this.age/this.deathAge);
-        }
-    }
-}

+ 0 - 594
src/objects/fireParticle/smoke/SmokeParticle.js

@@ -1,594 +0,0 @@
-import * as THREE from "../../../../libs/three.js/build/three.module.js";
-import Particle from './Particle.js'
-import Tween from '../Tween.js'
-import { vertexShader, fragmentShader } from './shader.js'
-
-const Type = Object.freeze({ "CUBE":1, "SPHERE":2 });
-let particleTexture  
-
-const getTexture = ()=>{
-    if(!particleTexture){
-        particleTexture = new THREE.TextureLoader().load( Potree.resourcePath+'/textures/smokeparticle.png')
-    }
-    return particleTexture
-}
-const boxGeo = new THREE.BoxBufferGeometry(1,1,1,1);
-const boxMat = new THREE.MeshBasicMaterial({wireframe:true, color:"#ffffff"})
-
-
-
-
-const defaults = 
-{
-    positions: [],
-    positionStyle    : "sphere",
-    positionBase     : new THREE.Vector3( 0, 0, 0 ),
- 
-    positionSpread   : new THREE.Vector3( 1, 1, 0), //cube
-     
-    radius   :   1,       // sphere
-        
-    velocityStyle    : 'cube',
-     
-    velocityBase     : new THREE.Vector3( 0,  0,  0.5),     // cube  基础速度
-    velocitySpread   : new THREE.Vector3( 1, 1, 0.3), 
-    
-    accelerationBase : 0.3,             //基础加速度
-    accelerationSpread : 0.6,	
-    
-    //没使用
-    speedBase  : 0.1,       //sphere
-    speedSpread : 0.5,
-          
-    
-
-    angleBase               : 0,
-    angleSpread             : 360,
-    angleVelocityBase       : 1,
-    angleVelocitySpread     : 30,
-    angleAccelerationBase   : 1,
-    angleAccelerationSpread : 5,
-        
-    sizeBase    :   0,  
-    sizeSpread  :   0,
-    sizeTween    : [[0, 0.3,   1], [0.3, 1.4,  6 ]], 
-    
-    
-    colorBase   :   new THREE.Vector3(0.0, 1.0, 0.5), 
-    colorSpread :   new THREE.Vector3(0.0, 0.0, 0.0),
-    colorTween   : new Tween( [0.2, 1], [ new THREE.Vector3(0,0,0.4), new THREE.Vector3(0, 0, 0.1) ] ),
-
-    opacityBase     :   0.1,//1.0,
-    opacitySpread   :   0.2,
-    opacityTween :[ [0, 0.1, 0.9, 1], [0.1, 0.4 , 0.03, 0 ] ], 
-     
-    //particlesPerSecond : 20,
-    strength : 1,
-    particleDeathAge   : 3,  //从底下升起后能持续的时间		
-    //emitterDeathAge    : 60 // time (seconds) at which to stop creating particles.
-    height : 3,
-};
-
-
-const debugSphere = new THREE.Mesh(new THREE.SphereBufferGeometry(0.03, 5,5), new THREE.MeshBasicMaterial({color:'white',depthTest:false}))
-
-export default class SmokeParticle extends THREE.Points{
-    constructor(prop={}) {
-        super()
-        
-         
-        this.blendStyle = THREE.NormalBlending; // false; 
-        this.emitterAge = 0.0;
-        //this.emitterAlive = true;
-       
-        prop = $.extend({}, defaults, prop)
-        for ( var key in prop ){
-            let value = prop[key] 
-            if(value instanceof Array && value[0] instanceof Array ) this[ key ] = new Tween(...value)
-            else if(value instanceof THREE.Vector3 || value instanceof THREE.Color){
-                this[ key ] = value.clone()
-            }else{
-                this[ key ] = value
-            }
-        }
-        
-        this.defaultSizeTween = this.sizeTween.clone()
-        this.defaultOpacityTween = this.opacityTween.clone()
-        
-        
-        this.geometry = new THREE.BufferGeometry()
-        this.computeParams()
-        this.createMaterial()
-        this.createGeometry()
-        
-        this.dynamic = true;
-        this.sortParticles = true; 
-        this.frustumCulled = false//似乎是禁止相机裁剪,否则会在某些角度消失。但是会不会更耗性能呢?
-       
-        prop.position && this.position.copy(prop.position)
-        
-        
-        
-        
-        //---------------------------------------
-        this.setSize({viewport:viewer.mainViewport})
-        this.setFov(viewer.fov)
-        
-        let setSize = (e)=>{
-            if(e.viewport.name != "MainView")return
-            this.setSize(e)
-        }
-        let setFov = (e)=>{
-            this.setFov(e.fov) 
-        }
-        /* let reStart = (e)=>{
-            if(e.v){//重新一个个放出粒子,否则会一股脑儿全部出来,因为同时大于粒子周期了一起重新生成出现。
-                setTimeout(()=>{//会先update一次delta为pageUnvisile的时间才触发 
-                    //console.log('归零') 
-                    //this.reStart()
-                },1) 
-            } 
-        } */
-        viewer.addEventListener('resize',setSize) 
-        viewer.addEventListener('fov_changed',setFov)
-        //viewer.addEventListener('pageVisible', reStart)
-        
-        this.addEventListener('dispose',()=>{
-            viewer.removeEventListener('resize',setSize) 
-            viewer.removeEventListener('fov_changed',setFov)
-            //viewer.removeEventListener('pageVisible', reStart)
-        })   
-        
-    }
-    
-    
-    
-    computeParams(){   
-         
-        let length = (this.curve ? this.curve.wholeLength : 0) + this.radius * 2 //加上首尾的半径
-        //注意:烟最低高度一米, 0<strength<1
-        if(this.positionStyle == 'cube'){
-            this.positionSpread.set(this.radius,this.radius,0)
-        } 
-        this.velocityBase.set(0,0, (this.height - 0.5 * this.accelerationBase * this.particleDeathAge * this.particleDeathAge) / this.particleDeathAge )
-        //let height = this.velocityBase.z * this.particleDeathAge + 0.5 * this.accelerationBase * this.particleDeathAge * this.particleDeathAge;//s = V0 * t + 0.5 * a * t*t ;     
-        this.velocityBase.z = Math.max(0,this.velocityBase.z);
-        this.particleCount =  Math.ceil(  length * Math.sqrt(this.strength * this.height * this.radius )   )  
-        this.particleCount = Math.max(5,this.particleCount)
-        { 
-            const minSize = 1, maxSize = 2, minBound = 0.01, maxBound = 1;
-            let size = minSize + (maxSize - minSize) * THREE.Math.smoothstep( this.strength, minBound, maxBound);
-                
-            this.sizeTween.values = this.defaultSizeTween.values.map(e=> e*size)
-        }
-        { 
-            const minSize = 1 , maxSize = 1.5, minBound = 0.01, maxBound = 1;
-            let opac = minSize + (maxSize - minSize) * THREE.Math.smoothstep( this.strength, minBound, maxBound);
-                
-            this.opacityTween.values = this.defaultOpacityTween.values.map(e=> e*opac )
-        }
-         
-        //console.log('smoke  particleCount',this.particleCount)
-        
-        
-        
-        
-    }
-
-    reStart(){
-        this.emitterAge = 0; 
-        this.createGeometry()  
-    }
-
-
-    updateGeometry(){ 
-        this.computeParams()
-        this.reStart() 
-        
-    }
-    
-    
-    createParticle(center)
-    {
-        var particle = new Particle({
-            sizeTween : this.sizeTween,
-            opacityTween : this.opacityTween,
-            colorTween : this.colorTween,
-        });
-        particle.deathAge = this.particleDeathAge
-        particle.center = center
-         
-        
-        if (this.positionStyle == 'cube')
-            particle.position = this.randomVector3( this.positionBase, this.positionSpread ); 
-        if (this.positionStyle == 'sphere')
-        {
-            /* var z = 2 * Math.random() - 1    
-            var t = Math.PI * 2 * Math.random();
-            var r = Math.sqrt( 1 - z*z ) ;
-            var vec3 = new THREE.Vector3( r * Math.cos(t), r * Math.sin(t), z );
-            particle.position = new THREE.Vector3().addVectors( this.positionBase, vec3.multiplyScalar( this.radius ) );
-           */
-            //怎么改半径
-            let y = 2 * Math.random() - 1    
-            let t = Math.PI * 2 * Math.random();
-            let r = Math.sqrt( 1 - y*y ) ; //因为 r*r = 1-y*y = x*x + z*z = r*r(cos^2 + sin^2 );
-            let lowDownRatio = 0.2 //压低近平面
-            let vec3 = new THREE.Vector3( r * Math.cos(t), y, Math.abs(r * Math.sin(t) ) * lowDownRatio);
-            particle.position = new THREE.Vector3().addVectors( this.positionBase, vec3.multiplyScalar( this.radius ) );
-           
-          
-        } 
-         
-        particle.position.add(center)//add
-         
-         
-         
-         
-         
-        if ( this.velocityStyle == 'cube' )
-        {
-            particle.velocity  = this.randomVector3( this.velocityBase,  this.velocitySpread ); 
-        }
-        if ( this.velocityStyle == 'sphere' )  
-        {
-            //var direction = particle.position.clone()
-            var direction = new THREE.Vector3(0,0,1) //烟应该都是向上的
-            var speed     = this.randomValue( this.speedBase, this.speedSpread );
-            particle.velocity  = direction.normalize().multiplyScalar( speed );
-        }
-        
-        particle.acceleration = this.randomValue( this.accelerationBase, this.accelerationSpread ); 
-
-        particle.angle             = this.randomValue( this.angleBase,             this.angleSpread );
-        particle.angleVelocity     = this.randomValue( this.angleVelocityBase,     this.angleVelocitySpread );
-        particle.angleAcceleration = this.randomValue( this.angleAccelerationBase, this.angleAccelerationSpread );
-
-        particle.size = this.randomValue( this.sizeBase, this.sizeSpread );
-
-        var color = this.randomVector3( this.colorBase, this.colorSpread );
-        particle.color = new THREE.Color().setHSL( color.x, color.y, color.z );
-        
-        particle.opacity = this.randomValue( this.opacityBase, this.opacitySpread );
-
-        particle.age   = 0;
-        particle.alive = 0; // particles initialize as inactive
-        return particle;
-    }			
-
-
-    getPointsForBound(){
-        return this.boundPoints; //可以用于expand实时bound的点, 不含particle的size等边距
-    }
-
-    getBound(points){ // points为生成点(圆心)
-        this.boundPoints = [] 
-        let boundingBox = new THREE.Box3()
-        
-        
-        let maxSize = this.sizeTween.values.slice().sort((a,b)=>b-a)[0]            
-        let margin0 = maxSize * 0.11
-        let margin1 = margin0 + 0.5   ;//保守估计还会飘出这么多距离吧: size + 飘动  
-        
-         
-        points.forEach(bottom=>{ 
-            let top = bottom.clone()
-            top.z +=  this.height 
-            boundingBox.expandByPoint(bottom);
-            boundingBox.expandByPoint(top); 
-            this.boundPoints.push(bottom,top)
-        })
-        let xyExpand = this.radius+margin1 
-        boundingBox.expandByVector(new THREE.Vector3(xyExpand,xyExpand,0))
-        boundingBox.min.z -= margin0 
-        boundingBox.max.z += margin1 
-       
-       
-       
-        this.boundingBox = boundingBox
-        
-        /* if(!this.debugBox){
-            this.debugBox = new THREE.Mesh(boxGeo, boxMat)
-            this.add(this.debugBox)
-        }
-        
-        this.debugBox.scale.copy(boundingBox.getSize(new THREE.Vector3))
-        this.debugBox.position.copy(boundingBox.getCenter(new THREE.Vector3))  */  
-         
-    }
-
-    createGeometry(){
-        this.particleArray = []
-        const positions = [];
-        const colors = [];
-        const alives = [];
-        const opacitys = [];
-        const sizes = [];
-        const angles = [];
-               
-        let count, points;
-        if(this.positions.length>1){
-             
-            const spaceDis = 0.6;//间隔距离
-            
-            count = Math.ceil(this.curve.wholeLength / spaceDis) + 1 
-             
-            points = this.curve.getSpacedPoints( count );  
-            
-            count = points.length
-            
-            /* points.forEach(e=>  { 
-                var sphere = debugSphere.clone();
-                sphere.position.copy(e)
-                viewer.scene.scene.add(sphere)
-            }) */
-            let haventGetPoints = points.slice() 
-            var getRanPoints = function(i){
-                var a = Math.random()
-                let choseIndex = Math.floor(haventGetPoints.length * a)
-                var point = haventGetPoints[choseIndex]
-                if(haventGetPoints.length == 1){
-                    haventGetPoints = points.slice()  
-                }else{
-                    haventGetPoints.splice(choseIndex, 1)
-                }
-                return point
-            }
-            
-            
-            this.getBound(points)
-        }else{
-            this.getBound(this.positions)
-        }
-        
-        
-        
-        
-        
-        for (var i = 0; i < this.particleCount; i++)
-        {
-            var center = new THREE.Vector3().copy(this.positions.length>1 ? getRanPoints(i)  : this.positions[0])
-             
-            //var center = new THREE.Vector3().copy(this.positions.length>1 ? points[Math.floor(i/this.particleCount * count)] : this.positions[0])
-              
-             
-            // remove duplicate code somehow, here and in update function below.
-            this.particleArray[i] = this.createParticle(center);
-            positions[3*i] = this.particleArray[i].position.x
-            positions[3*i+1] = this.particleArray[i].position.y
-            positions[3*i+2] = this.particleArray[i].position.z
-
-            colors[3*i] = this.particleArray[i].color.r 
-            colors[3*i+1] = this.particleArray[i].color.g
-            colors[3*i+2] = this.particleArray[i].color.b
-
-            alives[i] = this.particleArray[i].alive
-            opacitys[i] = this.particleArray[i].opacity
-            sizes[i] = this.particleArray[i].size
-            angles[i] = this.particleArray[i].angle
-        }
-
-        this.geometry.setAttribute( 'position', new THREE.BufferAttribute( new Float32Array(positions), 3  ));
-        this.geometry.setAttribute( 'customColor', new THREE.BufferAttribute( new Float32Array(colors), 3 ) );
-        this.geometry.setAttribute( 'customVisible', new THREE.BufferAttribute( new Float32Array(alives), 1 ) );
-        this.geometry.setAttribute( 'customOpacity', new THREE.BufferAttribute( new Float32Array(opacitys), 1 ) );
-        this.geometry.setAttribute( 'customSize', new THREE.BufferAttribute( new Float32Array(sizes), 1 ) );
-        this.geometry.setAttribute( 'customAngle', new THREE.BufferAttribute( new Float32Array(angles), 1 ) );
-    }
-    
-    createMaterial(){
-        this.material = new THREE.ShaderMaterial( 
-        {
-            uniforms: 
-            {
-                u_sampler:   { type: "t", value: getTexture() },
-                heightOfNearPlane: { type: "f", value:0}  //相对far ,以确保画面缩放时点的大小也会缩放
-            },
-            vertexShader:   vertexShader,vertexShader,
-            fragmentShader: fragmentShader,
-            transparent: true,
-            alphaTest: 0.5, // if having transparency issues, try including: alphaTest: 0.5, 
-            blending: this.blendStyle,
-            depthTest: this.blendStyle != THREE.NormalBlending
-        });
-        
-        
-        this.setPerspective(this.fov, this.screenHeight)
-        
-        
-    }
-    
-
-    update(dt){
-        if(!viewer.getObjVisiByReason(this,'force')){//被手动隐藏了
-            return
-        }
-        if(!Potree.Utils.isInsideFrustum(this.boundingBox, viewer.scene.getActiveCamera())){
-            viewer.updateVisible(this,'isInsideFrustum', false ) //不在视野范围
-            //console.log('unvi')
-            return
-        }else{
-            viewer.updateVisible(this,'isInsideFrustum', true )
-        } 
-        
-        
-        
-        if(dt > 1){
-            console.log('update dt>1', dt)
-        }
-         
-        //dt *= 0.5;
-        
-        const recycleIndices = [];
-        const recycleAges = []
-        
-        
-        const positions = [];
-        const colors = [];
-        const alives = [];
-        const opacitys = [];
-        const sizes = [];
-        const angles = [];
-    
-       
-        
-        
-        
-        
-        for (var i = 0; i < this.particleCount; i++)
-        {
-            if ( this.particleArray[i].alive )
-            {
-                  
-                if ( this.velocityStyle == 'cube' )
-                {        //一定几率改变下方向
-                    let ratio = Math.random()
-                    if(this.particleArray[i].age - this.particleArray[i].lastChangeVage > this.particleDeathAge*ratio  ){
-                        
-                        this.particleArray[i].velocity = this.randomVector3( this.velocityBase, this.velocitySpread ); 
-                        
-                        this.particleArray[i].lastChangeVage = this.particleArray[i].age
-                    }
-                }else{
-                    /* if(this.particleArray[i].age - this.particleArray[i].lastChangeVage > this.particleDeathAge*0.3  ){
-                        if( Math.random()>0.1){//一定几率改变下方向
-                            var speed  = this.randomValue( this.speedBase, this.speedSpread ); 
-                            this.particleArray[i].velocity = this.randomVector3( new THREE.Vector3,   new THREE.Vector3(1,1,1) ); 
-                            this.particleArray[i].velocity.normalize().multiplyScalar( speed );
-                        }
-                        this.particleArray[i].lastChangeVage = this.particleArray[i].age
-                    } */
-                    
-                    
-                }
-                 
-                
-                this.particleArray[i].update(dt);
-
-                // check if particle should expire
-                // could also use: death by size<0 or alpha<0.
-                if ( this.particleArray[i].age > this.particleDeathAge ) 
-                {
-                    this.particleArray[i].alive = 0.0;
-                    recycleIndices.push(i);
-                    recycleAges.push((this.particleArray[i].age - this.particleDeathAge)%(this.particleDeathAge ))
-                } 
-                
-                
-                // update particle properties in shader
-                positions[3*i] = this.particleArray[i].position.x
-                positions[3*i+1] = this.particleArray[i].position.y
-                positions[3*i+2] = this.particleArray[i].position.z
-
-                colors[3*i] = this.particleArray[i].color.r 
-                colors[3*i+1] = this.particleArray[i].color.g
-                colors[3*i+2] = this.particleArray[i].color.b
-
-                alives[i] = this.particleArray[i].alive
-                opacitys[i] = this.particleArray[i].opacity
-                sizes[i] = this.particleArray[i].size
-                angles[i] = this.particleArray[i].angle
-            }		
-        }
-
-        // check if particle emitter is still running
-        //if ( !this.emitterAlive ) return;
-
-        this.geometry.setAttribute( 'position', new THREE.BufferAttribute( new Float32Array(positions), 3 ) );
-        this.geometry.setAttribute( 'customColor', new THREE.BufferAttribute( new Float32Array(colors), 3 ) );
-        this.geometry.setAttribute( 'customVisible', new THREE.BufferAttribute( new Float32Array(alives), 1 ) );
-        this.geometry.setAttribute( 'customOpacity', new THREE.BufferAttribute( new Float32Array(opacitys), 1 ) );
-        this.geometry.setAttribute( 'customSize', new THREE.BufferAttribute( new Float32Array(sizes), 1 ) );
-        this.geometry.setAttribute( 'customAngle', new THREE.BufferAttribute( new Float32Array(angles), 1 ) );
-
-        this.geometry.attributes.customColor.needsUpdate = true;
-        this.geometry.attributes.customVisible.needsUpdate = true;
-        this.geometry.attributes.customOpacity.needsUpdate = true;
-        this.geometry.attributes.customSize.needsUpdate = true;
-        this.geometry.attributes.customAngle.needsUpdate = true;
-
-        // if no particles have died yet, then there are still particles to activate
-        if ( this.emitterAge < this.particleDeathAge ) //开始时一个个放出来
-        {
-            
-            let particlesPerSecond = this.particleCount / this.particleDeathAge
-            // determine indices of particles to activate
-            var startIndex = Math.round( particlesPerSecond * (this.emitterAge +  0) );
-            var endIndex = Math.round( particlesPerSecond * (this.emitterAge + dt) );
-            if  ( endIndex > this.particleCount ) 
-                endIndex = this.particleCount; 
-                
-            for (var i = startIndex; i < endIndex; i++)
-                this.particleArray[i].alive = 1.0;		
-        }
-
-        // if any particles have died while the emitter is still running, we imediately recycle them
-        for (var j = 0; j < recycleIndices.length; j++)
-        {
-            var i = recycleIndices[j]; 
-            this.particleArray[i] = this.createParticle(this.particleArray[i].center);
-            this.particleArray[i].alive = 1.0; // activate right away
-            this.particleArray[i].age = recycleAges[j]
-            positions[3*i] = this.particleArray[i].position.x
-            positions[3*i+1] = this.particleArray[i].position.y
-            positions[3*i+2] = this.particleArray[i].position.z
-        }
-        this.geometry.setAttribute( 'position', new THREE.BufferAttribute( new Float32Array(positions), 3 ) );
-        this.geometry.attributes.position.needsUpdate = true;
-
-        // stop emitter?
-        this.emitterAge += dt;
-        //if ( this.emitterAge > this.emitterDeathAge )  this.emitterAlive = false;
-    }
-
-    randomValue(base, spread)
-    {
-        //return base + spread * (Math.random() - 0.5);
-        let p = Math.random()
-        return base * p + spread * (1-p)
-        
-    }
-
-    randomVector3(base, spread)
-    {
-        var rand3 = new THREE.Vector3( Math.random() - 0.5, Math.random() - 0.5, Math.random() - 0.5 );
-        return new THREE.Vector3().addVectors( base, new THREE.Vector3().multiplyVectors( spread, rand3 ) );
-    }
-    
-    
-    
-    
-    setSize(e){
-        let viewport = e.viewport
-        this.screenHeight = viewport.resolution.y
-        this.setPerspective(this.fov, this.screenHeight)  
-    }
-    
-    setFov(fov){
-        this.fov = fov
-        this.setPerspective(this.fov, this.screenHeight) 
-    }
-    
-    
-    setPerspective(fov, height){
-        //this.uniforms.heightOfNearPlane.value = Math.abs(height / (2 * Math.tan(THREE.Math.degToRad(fov * 0.5))));
-        let far = Math.abs(height / (2 * Math.tan(THREE.Math.degToRad(fov * 0.5))));
-        this.material.uniforms.heightOfNearPlane.value = far 
-    }
-    
-    dispose(){
-        this.geometry.dispose();
-        this.material.dispose();
-        this.dispatchEvent('dispose') 
-    }
-}
-
-
-/* 
-    改进:如果有必要
-    
-    根据curve中分成的点,分成多个簇,每个簇掌管该部分的可见性和particle的数量。
-    在camera_changed时根据远近修改每个簇的particle的数量,当然不会大于初始创建的个数。多出的随机隐藏。
-
-
- */

+ 0 - 44
src/objects/fireParticle/smoke/shader.js

@@ -1,44 +0,0 @@
-export const vertexShader = `
-    attribute vec3  customColor;
-    attribute float customOpacity;
-    attribute float customSize;
-    attribute float customAngle;
-    attribute float customVisible;  
-    uniform float heightOfNearPlane;
-    
-    
-    varying vec4  vColor;
-    varying float vAngle;
-    void main()
-    {
-        if ( customVisible > 0.5 ) 				
-            vColor = vec4( customColor, customOpacity ); 
-        else							
-            vColor = vec4(0.0, 0.0, 0.0, 0.0);		
-            
-        vAngle = customAngle;
-
-        vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
-        //gl_PointSize = customSize * ( 300.0 / length( mvPosition.xyz ) );     
-        gl_Position = projectionMatrix * mvPosition;
-        gl_PointSize = ( heightOfNearPlane * customSize ) / gl_Position.w;
-        
-        
-    }
-` 
-
-export const fragmentShader = `
-    uniform sampler2D u_sampler;
-    varying vec4 vColor;	
-    varying float vAngle;  
-    void main()
-    {
-        gl_FragColor = vColor;
-        
-        float c = cos(vAngle);
-        float s = sin(vAngle);
-        vec2 rotatedUV = vec2(c * (gl_PointCoord.x - 0.5) + s * (gl_PointCoord.y - 0.5) + 0.5, c * (gl_PointCoord.y - 0.5) - s * (gl_PointCoord.x - 0.5) + 0.5);  
-        vec4 rotatedTexture = texture2D( u_sampler,  rotatedUV );
-        gl_FragColor = gl_FragColor * rotatedTexture;   
-    }
-`

+ 0 - 109
src/objects/tool/AnnotationTool.js

@@ -1,109 +0,0 @@
-
-import * as THREE from "../../../libs/three.js/build/three.module.js";
-import {Annotation} from "../../Annotation.js";
-import {Utils} from "../../utils.js";
-import {CameraMode} from "../../defines.js"; 
-import {ExtendEventDispatcher} from "../../custom/ExtendEventDispatcher.js";
-
-export class AnnotationTool extends ExtendEventDispatcher{
-	constructor (viewer) {
-		super();
-
-		this.viewer = viewer;
-		this.renderer = viewer.renderer;
-
-		this.sg = new THREE.SphereGeometry(0.1);
-		this.sm = new THREE.MeshNormalMaterial();
-		this.s = new THREE.Mesh(this.sg, this.sm);
-	}
-
-	startInsertion (args = {}) {
-		let domElement = this.viewer.renderer.domElement;
-
-		let annotation = new Annotation({
-			position: [589748.270, 231444.540, 753.675],
-			title: "Annotation Title",
-			description: `Annotation Description`,
-            radius: 1,//add
-            cameraPosition: [589748.270, 231444.540, 753.675],//add
-		});
-		this.dispatchEvent({type: 'start_inserting_annotation', annotation: annotation});
-
-		const annotations = this.viewer.scene.annotations;
-		annotations.add(annotation);
-
-		let callbacks = {
-			cancel: null,
-			finish: null,
-		};
-
-		let insertionCallback = (e) => {
-			if (e.button === THREE.MOUSE.LEFT) {
-				callbacks.finish();
-			} else if (e.button === THREE.MOUSE.RIGHT) {
-				callbacks.cancel();
-			}
-		};
-
-		callbacks.cancel = e => {
-			annotations.remove(annotation);
-
-			domElement.removeEventListener('mouseup', insertionCallback, true);
-		};
-
-		callbacks.finish = e => {
-			domElement.removeEventListener('mouseup', insertionCallback, true);
-		};
-
-		domElement.addEventListener('mouseup', insertionCallback, true);
-
-		let drag = (e) => {
-            let camera = e.viewer.scene.getActiveCamera()  
-			/* let I = Utils.getMousePointCloudIntersection(
-				e.drag.end, 
-				camera, 
-				e.viewer, 
-				e.viewer.scene.pointclouds,
-				{pickClipped: true}); */
-            let I = e.viewer.inputHandler.intersectPoint
-
-			if (I) {
-				this.s.position.copy(I.location);
-
-				annotation.position.copy(I.location);
-                
-                annotation.cameraTarget.copy(I.location);//add
-                annotation.cameraPosition.copy(camera.position);//add
-			}
-		};
-
-		let drop = (e) => {
-			viewer.scene.scene.remove(this.s);
-			this.s.removeEventListener("drag", drag);
-			this.s.removeEventListener("drop", drop);
-		};
-
-		this.s.addEventListener('drag', drag);
-		this.s.addEventListener('drop', drop);
-
-		this.viewer.scene.scene.add(this.s);
-		this.viewer.inputHandler.startDragging(this.s);
-
-		return annotation;
-	}
-	
-	update(){
-		// let camera = this.viewer.scene.getActiveCamera();
-		// let domElement = this.renderer.domElement;
-		// let measurements = this.viewer.scene.measurements;
-
-		// const renderAreaSize = this.renderer.getSize(new THREE.Vector2());
-		// let clientWidth = renderAreaSize.width;
-		// let clientHeight = renderAreaSize.height;
-
-	}
-
-	render(){
-		//this.viewer.renderer.render(this.scene, this.viewer.scene.getActiveCamera());
-	}
-};

+ 0 - 37
src/objects/tool/Box3Helper.js

@@ -1,37 +0,0 @@
-/**
- *
- * code adapted from three.js BoxHelper.js
- * https://github.com/mrdoob/three.js/blob/dev/src/helpers/BoxHelper.js
- *
- * @author mrdoob / http://mrdoob.com/
- * @author Mugen87 / http://github.com/Mugen87
- * @author mschuetz / http://potree.org
- */
-
-import * as THREE from "../../../libs/three.js/build/three.module.js";
-
-export class Box3Helper extends THREE.LineSegments {
-	constructor (box, color) {
-		if (color === undefined) color = 0xffff00;
-
-		let indices = new Uint16Array([ 0, 1, 1, 2, 2, 3, 3, 0, 4, 5, 5, 6, 6, 7, 7, 4, 0, 4, 1, 5, 2, 6, 3, 7 ]);
-		let positions = new Float32Array([
-			box.min.x, box.min.y, box.min.z,
-			box.max.x, box.min.y, box.min.z,
-			box.max.x, box.min.y, box.max.z,
-			box.min.x, box.min.y, box.max.z,
-			box.min.x, box.max.y, box.min.z,
-			box.max.x, box.max.y, box.min.z,
-			box.max.x, box.max.y, box.max.z,
-			box.min.x, box.max.y, box.max.z
-		]);
-
-		let geometry = new THREE.BufferGeometry();
-		geometry.setIndex(new THREE.BufferAttribute(indices, 1));
-		geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));
-
-		let material = new THREE.LineBasicMaterial({ color: color });
-
-		super(geometry, material);
-	}
-}

+ 0 - 290
src/objects/tool/ClipVolume.js

@@ -1,290 +0,0 @@
-
-import * as THREE from "../../../libs/three.js/build/three.module.js";
-
-export class ClipVolume extends THREE.Object3D{
-	
-	constructor(args={}){
-		super();
-		
-		this.constructor.counter = (this.constructor.counter === undefined) ? 0 : this.constructor.counter + 1;
-		this.name = "clip_volume_" + this.constructor.counter;
-
-		let alpha = args.alpha || 0;
-		let beta = args.beta || 0;
-		let gamma = args.gamma || 0;
-
-		this.rotation.x = alpha;
-		this.rotation.y = beta;
-		this.rotation.z = gamma;
-
-		this.clipOffset = 0.001;
-		this.clipRotOffset = 1;
-				
-		let boxGeometry = new THREE.BoxGeometry(1, 1, 1);
-		boxGeometry.computeBoundingBox();
-		
-		let boxFrameGeometry = new THREE.Geometry();
-		{			
-			// bottom
-			boxFrameGeometry.vertices.push(new THREE.Vector3(-0.5, -0.5, 0.5));
-			boxFrameGeometry.vertices.push(new THREE.Vector3(0.5, -0.5, 0.5));
-			boxFrameGeometry.vertices.push(new THREE.Vector3(0.5, -0.5, 0.5));
-			boxFrameGeometry.vertices.push(new THREE.Vector3(0.5, -0.5, -0.5));
-			boxFrameGeometry.vertices.push(new THREE.Vector3(0.5, -0.5, -0.5));
-			boxFrameGeometry.vertices.push(new THREE.Vector3(-0.5, -0.5, -0.5));
-			boxFrameGeometry.vertices.push(new THREE.Vector3(-0.5, -0.5, -0.5));
-			boxFrameGeometry.vertices.push(new THREE.Vector3(-0.5, -0.5, 0.5));
-			// top
-			boxFrameGeometry.vertices.push(new THREE.Vector3(-0.5, 0.5, 0.5));
-			boxFrameGeometry.vertices.push(new THREE.Vector3(0.5, 0.5, 0.5));
-			boxFrameGeometry.vertices.push(new THREE.Vector3(0.5, 0.5, 0.5));
-			boxFrameGeometry.vertices.push(new THREE.Vector3(0.5, 0.5, -0.5));
-			boxFrameGeometry.vertices.push(new THREE.Vector3(0.5, 0.5, -0.5));
-			boxFrameGeometry.vertices.push(new THREE.Vector3(-0.5, 0.5, -0.5));
-			boxFrameGeometry.vertices.push(new THREE.Vector3(-0.5, 0.5, -0.5));
-			boxFrameGeometry.vertices.push(new THREE.Vector3(-0.5, 0.5, 0.5));
-			// sides
-			boxFrameGeometry.vertices.push(new THREE.Vector3(-0.5, -0.5, 0.5));
-			boxFrameGeometry.vertices.push(new THREE.Vector3(-0.5, 0.5, 0.5));
-			boxFrameGeometry.vertices.push(new THREE.Vector3(0.5, -0.5, 0.5));
-			boxFrameGeometry.vertices.push(new THREE.Vector3(0.5, 0.5, 0.5));
-			boxFrameGeometry.vertices.push(new THREE.Vector3(0.5, -0.5, -0.5));
-			boxFrameGeometry.vertices.push(new THREE.Vector3(0.5, 0.5, -0.5));
-			boxFrameGeometry.vertices.push(new THREE.Vector3(-0.5, -0.5, -0.5));
-			boxFrameGeometry.vertices.push(new THREE.Vector3(-0.5, 0.5, -0.5));
-
-			boxFrameGeometry.colors.push(new THREE.Vector3(1, 1, 1));
-		}
-
-		let planeFrameGeometry = new THREE.Geometry();
-		{						
-			// middle line
-			planeFrameGeometry.vertices.push(new THREE.Vector3(-0.5, -0.5, 0.0));
-			planeFrameGeometry.vertices.push(new THREE.Vector3(-0.5, 0.5, 0.0));
-			planeFrameGeometry.vertices.push(new THREE.Vector3(0.5, 0.5, 0.0));
-			planeFrameGeometry.vertices.push(new THREE.Vector3(0.5, -0.5, 0.0));
-			planeFrameGeometry.vertices.push(new THREE.Vector3(-0.5, 0.5, 0.0));
-			planeFrameGeometry.vertices.push(new THREE.Vector3(0.5, 0.5, 0.0));
-			planeFrameGeometry.vertices.push(new THREE.Vector3(-0.5, -0.5, 0.0));
-			planeFrameGeometry.vertices.push(new THREE.Vector3(0.5, -0.5, 0.0));
-		}
-
-		this.dimension = new THREE.Vector3(1, 1, 1);
-		this.material = new THREE.MeshBasicMaterial( {
-			color: 0x00ff00, 
-			transparent: true, 
-			opacity: 0.3,
-			depthTest: true, 
-			depthWrite: false} );
-		this.box = new THREE.Mesh(boxGeometry, this.material);
-		this.box.geometry.computeBoundingBox();
-		this.boundingBox = this.box.geometry.boundingBox;
-		this.add(this.box);
-		
-		this.frame = new THREE.LineSegments( boxFrameGeometry, new THREE.LineBasicMaterial({color: 0x000000}));
-		this.add(this.frame);
-		this.planeFrame = new THREE.LineSegments( planeFrameGeometry, new THREE.LineBasicMaterial({color: 0xff0000}));
-		this.add(this.planeFrame);
-
-		// set default thickness
-		this.setScaleZ(0.1);
-
-		// create local coordinate system
-		let createArrow = (name, direction, color) => {
-			let material = new THREE.MeshBasicMaterial({
-				color: color, 
-				depthTest: false, 
-				depthWrite: false});
-				
-			let shaftGeometry = new THREE.Geometry();
-			shaftGeometry.vertices.push(new THREE.Vector3(0, 0, 0));
-			shaftGeometry.vertices.push(new THREE.Vector3(0, 1, 0));
-			
-			let shaftMaterial = new THREE.LineBasicMaterial({
-				color: color, 
-				depthTest: false, 
-				depthWrite: false,
-				transparent: true
-				});
-			let shaft = new THREE.Line(shaftGeometry, shaftMaterial);
-			shaft.name = name + "_shaft";
-			
-			let headGeometry = new THREE.CylinderGeometry(0, 0.04, 0.1, 10, 1, false);
-			let headMaterial = material;
-			let head = new THREE.Mesh(headGeometry, headMaterial);
-			head.name = name + "_head";
-			head.position.y = 1;
-			
-			let arrow = new THREE.Object3D();
-			arrow.name = name;
-			arrow.add(shaft);
-			arrow.add(head);
-
-			return arrow;
-		};
-		
-		this.arrowX = createArrow("arrow_x", new THREE.Vector3(1, 0, 0), 0xFF0000);
-		this.arrowY = createArrow("arrow_y", new THREE.Vector3(0, 1, 0), 0x00FF00);
-		this.arrowZ = createArrow("arrow_z", new THREE.Vector3(0, 0, 1), 0x0000FF);
-		
-		this.arrowX.rotation.z = -Math.PI / 2;
-		this.arrowZ.rotation.x = Math.PI / 2;
-
-		this.arrowX.visible = false;
-		this.arrowY.visible = false;
-		this.arrowZ.visible = false;
-
-		this.add(this.arrowX);
-		this.add(this.arrowY);
-		this.add(this.arrowZ);
-		
-		{ // event listeners
-			this.addEventListener("ui_select", e => { 
-				this.arrowX.visible = true;
-				this.arrowY.visible = true;
-				this.arrowZ.visible = true; 
-			});
-			this.addEventListener("ui_deselect", e => {
-				this.arrowX.visible = false;
-				this.arrowY.visible = false;
-				this.arrowZ.visible = false; 				
-			});
-			this.addEventListener("select", e => { 
-				let scene_header = $("#" + this.name + " .scene_header");
-				if(!scene_header.next().is(":visible")) {
-					scene_header.click();
-				}
-			});
-			this.addEventListener("deselect", e => { 
-				let scene_header = $("#" + this.name + " .scene_header");
-				if(scene_header.next().is(":visible")) {
-					scene_header.click();
-				}
-			});
-		}
-		
-		this.update();
-	};
-
-	setClipOffset(offset) {		
-		this.clipOffset = offset;	
-	}
-
-	setClipRotOffset(offset) {		
-		this.clipRotOffset = offset;		
-	}
-
-	setScaleX(x) {
-		this.box.scale.x = x;
-		this.frame.scale.x = x;
-		this.planeFrame.scale.x = x;			
-	}
-
-	setScaleY(y) {
-		this.box.scale.y = y;
-		this.frame.scale.y = y;
-		this.planeFrame.scale.y = y;		
-	}
-
-	setScaleZ(z) {
-		this.box.scale.z = z;
-		this.frame.scale.z = z;
-		this.planeFrame.scale.z = z;		
-	}
-
-	offset(args) {
-		let cs = args.cs || null;
-		let axis = args.axis || null;
-		let dir = args.dir || null;
-
-		if(!cs || !axis || !dir) return;
-
-		if(axis === "x") {
-			if(cs === "local") {
-				this.position.add(this.localX.clone().multiplyScalar(dir * this.clipOffset));
-			} else if(cs === "global") {
-				this.position.x = this.position.x + dir * this.clipOffset;
-			}
-		}else if(axis === "y") {
-			if(cs === "local") {
-				this.position.add(this.localY.clone().multiplyScalar(dir * this.clipOffset));
-			} else if(cs === "global") {
-				this.position.y = this.position.y + dir * this.clipOffset;
-			}
-		}else if(axis === "z") {
-			if(cs === "local") {
-				this.position.add(this.localZ.clone().multiplyScalar(dir * this.clipOffset));
-			} else if(cs === "global") {
-				this.position.z = this.position.z + dir * this.clipOffset;
-			}
-		}
-
-		this.dispatchEvent({"type": "clip_volume_changed", "viewer": viewer, "volume": this});
-	}	
-
-	rotate(args) {
-		let cs = args.cs || null;
-		let axis = args.axis || null;
-		let dir = args.dir || null;
-
-		if(!cs || !axis || !dir) return;
-
-		if(cs === "local") {
-			if(axis === "x") {
-				this.rotateOnAxis(new THREE.Vector3(1, 0, 0), dir * this.clipRotOffset * Math.PI / 180);
-			} else if(axis === "y") {
-				this.rotateOnAxis(new THREE.Vector3(0, 1, 0), dir * this.clipRotOffset * Math.PI / 180);
-			} else if(axis === "z") {
-				this.rotateOnAxis(new THREE.Vector3(0, 0, 1), dir * this.clipRotOffset * Math.PI / 180);
-			}
-		} else if(cs === "global") {
-			let rotaxis = new THREE.Vector4(1, 0, 0, 0);	
-			if(axis === "y") {
-				rotaxis = new THREE.Vector4(0, 1, 0, 0);
-			} else if(axis === "z") {
-				rotaxis = new THREE.Vector4(0, 0, 1, 0);
-			}
-			this.updateMatrixWorld();
-			let invM = newthis.matrixWorld.clone().invert();
-			rotaxis = rotaxis.applyMatrix4(invM).normalize();
-			rotaxis = new THREE.Vector3(rotaxis.x, rotaxis.y, rotaxis.z);
-			this.rotateOnAxis(rotaxis, dir * this.clipRotOffset * Math.PI / 180);
-		}
-
-		this.updateLocalSystem();
-
-		this.dispatchEvent({"type": "clip_volume_changed", "viewer": viewer, "volume": this});
-	}	
-
-	update(){
-		this.boundingBox = this.box.geometry.boundingBox;
-		this.boundingSphere = this.boundingBox.getBoundingSphere(new THREE.Sphere());
-		
-		this.box.visible = false;
-
-		this.updateLocalSystem();
-	};
-
-	updateLocalSystem() {		
-		// extract local coordinate axes
-		let rotQuat = this.getWorldQuaternion();
-		this.localX = new THREE.Vector3(1, 0, 0).applyQuaternion(rotQuat).normalize();
-		this.localY = new THREE.Vector3(0, 1, 0).applyQuaternion(rotQuat).normalize();
-		this.localZ = new THREE.Vector3(0, 0, 1).applyQuaternion(rotQuat).normalize();
-	}
-	
-	raycast(raycaster, intersects){
-		
-		let is = [];
-		this.box.raycast(raycaster, is);
-	
-		if(is.length > 0){
-			let I = is[0];
-			intersects.push({
-				distance: I.distance,
-				object: this,
-				point: I.point.clone()
-			});
-		}
-	};
-};

+ 0 - 185
src/objects/tool/ClippingTool.js

@@ -1,185 +0,0 @@
-
-
-import * as THREE from "../../../libs/three.js/build/three.module.js";
-import {ClipVolume} from "./ClipVolume.js";
-import {PolygonClipVolume} from "./PolygonClipVolume.js"; 
-import {ExtendEventDispatcher} from "../../custom/ExtendEventDispatcher.js";
-
-export class ClippingTool extends ExtendEventDispatcher{
-
-	constructor(viewer){
-		super(); 
-
-		this.viewer = viewer;
-
-		this.maxPolygonVertices = 8; 
-		
-		this.addEventListener("start_inserting_clipping_volume", e => {
-			this.viewer.dispatchEvent({
-				type: "cancel_insertions"
-			});
-		});
-
-		this.sceneMarker = new THREE.Scene();
-		this.sceneVolume = new THREE.Scene();
-		this.sceneVolume.name = "scene_clip_volume";
-		this.viewer.inputHandler.registerInteractiveScene(this.sceneVolume);
-
-		this.onRemove = e => {
-			this.sceneVolume.remove(e.volume);
-		};
-		
-		this.onAdd = e => {
-			this.sceneVolume.add(e.volume);
-		};
-		
-		this.viewer.inputHandler.addEventListener("delete", e => {
-			let volumes = e.selection.filter(e => (e instanceof ClipVolume));
-			volumes.forEach(e => this.viewer.scene.removeClipVolume(e));
-			let polyVolumes = e.selection.filter(e => (e instanceof PolygonClipVolume));
-			polyVolumes.forEach(e => this.viewer.scene.removePolygonClipVolume(e));
-		});
-        
-        
-        
-        
-        
-        
-        
-        //----
-        
-        /* var a = new ClipVolume()
-        viewer.scene.addVolume(a);
-        viewer.setObjectLayers(a, 'volume' ) */
-	}
-
-	setScene(scene){
-		if(this.scene === scene){
-			return;
-		}
-		
-		if(this.scene){
-			this.scene.removeEventListeners("clip_volume_added", this.onAdd);
-			this.scene.removeEventListeners("clip_volume_removed", this.onRemove);
-			this.scene.removeEventListeners("polygon_clip_volume_added", this.onAdd);
-			this.scene.removeEventListeners("polygon_clip_volume_removed", this.onRemove);
-		}
-		
-		this.scene = scene;
-		
-		this.scene.addEventListener("clip_volume_added", this.onAdd);
-		this.scene.addEventListener("clip_volume_removed", this.onRemove);
-		this.scene.addEventListener("polygon_clip_volume_added", this.onAdd);
-		this.scene.addEventListener("polygon_clip_volume_removed", this.onRemove);
-	}
-
-	startInsertion(args = {}) {	
-		let type = args.type || null;
-
-		if(!type) return null;
-
-		let domElement = this.viewer.renderer.domElement;
-		let canvasSize = this.viewer.renderer.getSize(new THREE.Vector2());
-
-		let svg = $(`
-		<svg height="${canvasSize.height}" width="${canvasSize.width}" style="position:absolute; pointer-events: none">
-
-			<defs>
-				 <marker id="diamond" markerWidth="24" markerHeight="24" refX="12" refY="12"
-						markerUnits="userSpaceOnUse">
-					<circle cx="12" cy="12" r="6" fill="white" stroke="black" stroke-width="3"/>
-				</marker>
-			</defs>
-
-			<polyline fill="none" stroke="black" 
-				style="stroke:rgb(0, 0, 0);
-				stroke-width:6;"
-				stroke-dasharray="9, 6"
-				stroke-dashoffset="2"
-				/>
-
-			<polyline fill="none" stroke="black" 
-				style="stroke:rgb(255, 255, 255);
-				stroke-width:2;"
-				stroke-dasharray="5, 10"
-				marker-start="url(#diamond)" 
-				marker-mid="url(#diamond)" 
-				marker-end="url(#diamond)" 
-				/>
-		</svg>`);
-		$(domElement.parentElement).append(svg);
-
-		let polyClipVol = new PolygonClipVolume(this.viewer.scene.getActiveCamera().clone());
-
-		this.dispatchEvent({"type": "start_inserting_clipping_volume"});
-
-		this.viewer.scene.addPolygonClipVolume(polyClipVol);
-		this.sceneMarker.add(polyClipVol);
-
-		let cancel = {
-			callback: null
-		};
-
-		let insertionCallback = (e) => {
-			if(e.button === THREE.MOUSE.LEFT){
-				
-				polyClipVol.addMarker();
-
-				// SVC Screen Line
-				svg.find("polyline").each((index, target) => {
-					let newPoint = svg[0].createSVGPoint();
-					newPoint.x = e.offsetX;
-					newPoint.y = e.offsetY;
-					let polyline = target.points.appendItem(newPoint);
-				});
-				
-				
-				if(polyClipVol.markers.length > this.maxPolygonVertices){
-					cancel.callback();
-				}
-				
-				this.viewer.inputHandler.startDragging(
-					polyClipVol.markers[polyClipVol.markers.length - 1]);
-			}else if(e.button === THREE.MOUSE.RIGHT){
-				cancel.callback(e);
-			}
-		};
-		
-		cancel.callback = e => {
-
-			//let first = svg.find("polyline")[0].points[0];
-			//svg.find("polyline").each((index, target) => {
-			//	let newPoint = svg[0].createSVGPoint();
-			//	newPoint.x = first.x;
-			//	newPoint.y = first.y;
-			//	let polyline = target.points.appendItem(newPoint);
-			//});
-			svg.remove();
-
-			if(polyClipVol.markers.length > 3) {
-				polyClipVol.removeLastMarker();
-				polyClipVol.initialized = true;	
-			} else {
-				this.viewer.scene.removePolygonClipVolume(polyClipVol);
-			}
-
-			this.viewer.renderer.domElement.removeEventListener("mouseup", insertionCallback, true);
-			this.viewer.removeEventListener("cancel_insertions", cancel.callback);
-			this.viewer.inputHandler.enabled = true;
-		};
-		
-		this.viewer.addEventListener("cancel_insertions", cancel.callback);
-		this.viewer.renderer.domElement.addEventListener("mouseup", insertionCallback , true);
-		this.viewer.inputHandler.enabled = false;
-		
-		polyClipVol.addMarker();
-		this.viewer.inputHandler.startDragging(
-			polyClipVol.markers[polyClipVol.markers.length - 1]);
-
-		return polyClipVol;
-	}
-
-	update() {
-
-	}
-};

+ 0 - 297
src/objects/tool/Compass.js

@@ -1,297 +0,0 @@
- 
-import * as THREE from "../../../libs/three.js/build/three.module.js";
-import {ExtendEventDispatcher} from "../../custom/ExtendEventDispatcher.js";
-
-
-const initDir = new THREE.Vector3(0,1,0)//指南针模型的北方向 向屏幕里
-
-class Compass extends ExtendEventDispatcher{
-    
-    constructor(dom, viewport){
-        super()
-        this.angle = 0;
-        this.show = false; 
-        if(dom){
-            this.dom = $(dom);
-        }
-        
-        this.viewport = viewport
-        this.init()
-        
-
-        
-
-    }
-    init(){ 
-        var width = 100, height = 100
-        if(!this.dom){ 
-            this.dom = $('<div name="compass"></div>')
-            $(viewer.renderArea).append(this.dom)
-        } 
-        this.dom.css({ display:"none",  position:"absolute",right:"1%",top: "60px",width:width+"px",height:height+"px", "z-index":100,"pointer-events":"none" })
-
-        let child = $("<div class='dirText north'><span>"+/* (config.lang=='zh'? */'北'/* :'N') */+"</span></div><div class='center'></div>")
-        this.dom.append(child)  
-
-         
-        this.dom.find(".dirText").css({textAlign:"center","font-size":"10px","position":"absolute",
-                width: "100%",
-                height: "25px",
-        "line-height": "25px"})
-         
-        this.dom.find(".north").css({"color":"#02a0e9","top":"0"})
-        this.dom.find(".south").css({"color":"#ff1414","bottom":"0"})
-        this.dom.find(".center").css({
-            //"background":`url(${config.getStaticResource('img')}/dire.png)`,
-            width: width/2+"px",
-            height: height/2+"px",
-            "background-size": "contain",
-            "background-position": "center",
-            left: "50%",
-            top: "50%",
-            transform: "translate(-50%,-50%)",
-            position: "absolute" 
-        })
-        this.dom.find(".dirText").css({
-            "text-align": "center",
-            "font-size": "10px", 
-            "color": "rgb(255, 255, 255)",
-            "position": "absolute",
-            "top": "50%",
-            "left": "50%",
-            "width": "45%",
-            "height": "0px",
-            "transform-origin": "left center",
-            
-        })
-        this.dom.find(".dirText span").css({
-            display: "block",
-            position: "absolute",
-            right: "5px",
-            top: "0",
-            width: "20px",
-            height: "20px",
-            "line-height": "20px", 
-           // "font-size": ".75rem ",
-            "margin-top": "-10px",
-            
-        })   
-    
-        try { 
-            this.renderer = new THREE.WebGLRenderer({ antialias: true, alpha:true })//许钟文 添加个抗锯齿,否则添加的线条锯齿严重,
-            this.renderer.autoClear = !0
-            this.renderer.setPixelRatio(window.devicePixelRatio ? window.devicePixelRatio : 1)
-            this.renderer.domElement.setAttribute('name','compass')
-            this.renderer.setClearAlpha(0.0)
-            //xst修改
-			//this.renderer.setSize(width/2, height/2, false, window.devicePixelRatio ? window.devicePixelRatio : 1);
-            //xst修改
-			//this.renderer.setPixelRatio(window.devicePixelRatio ? window.devicePixelRatio : 1);
-			//this.renderer.setSize(width/2, height/2);
-			//xst修改
-			this.renderer.setDrawingBufferSize( width/2, height/2, window.devicePixelRatio ? window.devicePixelRatio : 1 )
-			//this.emit(SceneRendererEvents.ContextCreated)
-        } catch (e) {
-            viewer.dispatchEvent('webglError', {msg:e})
-        }
-        
-        this.dom.find(".center")[0].appendChild(this.renderer.domElement);
-        this.renderer.domElement.style.width = this.renderer.domElement.style.height = '100%'
-        
-        
-        this.camera = new THREE.PerspectiveCamera;
-        this.camera.fov = 50;
-        this.camera.updateProjectionMatrix()
-        this.scene = new THREE.Scene,
-        this.scene.add(this.camera)
-        
-        
-        
-        this.createCompass()
-          
-        viewer.addEventListener('camera_changed', e => {
-            if (e.viewport == this.viewport && (e.changeInfo.positionChanged || e.changeInfo.quaternionChanged)) {
-                 this.update()
-            } 
-        })
-        
-        this.setDomPos()
-        if(this.viewport)this.setDisplay(true)
-    }   
-        
-        
-    createCompass(){
-        //ConeBufferGeometry(radius : Float, height : Float, radialSegments : Integer, heightSegments : Integer, openEnded : Boolean, thetaStart : Float, thetaLength : Float)
-        const height = 2;
-        const geometry1 = new THREE.ConeBufferGeometry( 0.7, height, 4, true );
-        const geometry2 = new THREE.ConeBufferGeometry( 0.7, height, 4, true );
-        const material = new THREE.MeshBasicMaterial({   
-             vertexColors :true
-        })
-        
-        //指南针由两个四棱锥拼成,为了渐变颜色,采用指定vertexColor的方式。
-        var setColor = function(geometry, color1,color2){ 
-            const colors = [];
-            for ( let i = 0, n = geometry.attributes.position.count; i < n; ++ i ) { 
-                colors.push( 1, 1, 1 ); 
-            } 
-            var set = function(index, color){//设置第index个点的颜色
-                colors[index*3+0] = color[0]
-                colors[index*3+1] = color[1]
-                colors[index*3+2] = color[2]
-            }
-            var mid = [(color1[0]+color2[0])/2, (color1[1]+color2[1])/2, (color1[2]+color2[2])/2 ]
-            set(1,color1); set(5,color1);set(6,color1);
-            set(2,mid); set(3,mid);set(7,mid);
-            set(4,color2); set(8,color2);set(9,color2);
-            geometry.setAttribute("color", new THREE.BufferAttribute(new Float32Array(colors), 3))  
-        }
-        var blue1 = [1/255,238/255,245/255] //逐渐变深
-        var blue2 = [20/255,146/255,170/255]
-        var blue3 = [40/255,60/255,103/255]
-        setColor(geometry1, blue1,blue2)
-        setColor(geometry2, blue2,blue3)
-        
-        /*  朝箭头方向看点构成如下  虽然geometry.attributes.position.count = 19  只有1-9设置的颜色是有效的  另外为什么7决定了上下两边的颜色呢…… 5、9可将其分成上下两个颜色
-             6 
-            /|\   
-           / | \
-        7 /_2|1_\ 5
-          \ 3|4 / 9
-           \ | /
-            \|/
-             8
-         */
-        const cone = new THREE.Mesh( geometry1, material );
-        cone.position.setY(height/2)
-        geometry1.computeVertexNormals()//computeFaceNormals
-        geometry2.computeVertexNormals()
-        
-        const cones = new THREE.Object3D();
-        cones.add(cone)
-         
-        let cone2 = new THREE.Mesh( geometry2, material );
-        cone2.rotation.x = Math.PI;
-        cone2.position.setY(-height/2)
-        cones.add(cone2)  
-        //cones.rotation.x = Math.PI / 2;//转向initDir的方向
-        //cones.rotation.z = Math.PI / 2;
-        cones.rotation.z = Math.PI ;//转向initDir的方向
-        cones.scale.set(0.7,0.7,0.7)
-        this.scene.add(cones)
-        this.cones = cones
-    }
-    
-    
-    
-    setNorth(){ //设置北方向,这决定了指南针自身的朝向。 
-        const floors = store.getters['scene/houstFloor'].floors
-        if(!floors || !floors.length){
-            return 
-        }
-        const floor = floors[0] 
-        const metadata = app.store.getters['scene/metadata'] || {}
-         
-        this.angle = (floor && floor.dire || 0) + THREE.Math.radToDeg(parseFloat(metadata.floorPlanAngle || 0))  //基础朝向  
-        this.cones.rotation.y = Math.PI / 2 - THREE.Math.degToRad(this.angle) 
-        //console.log("dir:"+floor.dire+", floorPlanAngle:"+metadata.floorPlanAngle)
-        this.update() 
-   
-    }
-    
-    update(quaternion){
-        if(!this.show)return;
-        if(!quaternion) quaternion = this.viewport.camera.quaternion.clone();
-        this.updateCamera(quaternion)
-        this.updateLabel(quaternion)
-        this.render()
-         
-    }
-    
-    
-    /*updateLabel(quaternion){//更新北标签
-          
-        var dir = viewer.mainViewport.view.direction;
-        var oriDir = initDir.clone()  //指南针最初始时的北方向
-        var extraQua 
-        if(objects.player.mode == "transitioning"){//当transitioning时,相机的quaternion不是用control的lookAt算出来,而是直接由一个quaternion过渡到另一个,这样相机将会是歪的,投影面也就不会是原先的水平面。
-            var tempCamera = new THREE.Camera();   //借用camera的lookAt算出如果正视同样的target, quaternion会是什么值。 将它乘以当前相机quaternion,得到的就是相机歪的旋转值。
-            tempCamera.position.copy(this.camera.position); 
-            tempCamera.lookAt(tempCamera.position.clone().add(dir)) 
-            var q = tempCamera.quaternion.inverse()
-            extraQua = q.premultiply(quaternion) //歪掉的额外旋转值
-            
-        }  
-         
-        //北标签的方向为指南针轮盘方向,也就是要将camera的方向投影到水平面上。 但是如果相机歪了,看到的世界都会歪一定角度,投影面也要歪一定角度。
-        var up = new THREE.Vector3(0,0,1) //投影水平面的法线,也是相机的摆正的up方向
-        extraQua && up.applyQuaternion(extraQua)
-        dir.projectOnPlane(up)   //将方向投影到水平面上; 如果相机不是正视(extraQua不为0001),就要将水平面也转动 
-        oriDir.projectOnPlane(up)//为什么initDir投影了和没有投影angle结果一样 
-        var angle = dir.angleTo(oriDir)
-        if(dir.cross(oriDir).y > 0)angle = -angle
-         
-        var deg = this.angle - 90 + THREE.Math.radToDeg(angle) //因为css写的样式初始是指向右方,和initDir差了90°,所以减去。
-        
-        
-        this.dom.find(".dirText").css( "transform","rotate("+deg+"deg)" )
-        this.dom.find(".dirText span").css("transform","rotate("+(-deg)+"deg)")
-    } */
-    
-
-
-    updateLabel(quaternion){//更新北标签
-        let deg = THREE.Math.radToDeg(this.viewport.view.yaw) - 90
-        this.dom.find(".dirText").css( "transform","rotate("+deg+"deg)" )
-        this.dom.find(".dirText span").css("transform","rotate("+(-deg)+"deg)")
-    }
-
-    
-    updateCamera(quaternion){ //更新canvas中的指南针表现,也就是更新相机,和场景中的相机朝向一致。 
-         const radius = 5;  //相机距离
-          
-         this.camera.quaternion.copy(quaternion);
-         var dir = this.viewport.view.direction;  //相机朝向
-         this.camera.position.copy(dir.multiplyScalar(radius).negate())  //相机绕着指南针中心(000)转动
-    } 
-
-    changeViewport(viewport){
-        this.viewport = viewport;
-        this.update(); //因相机更新了
-    }
-
-
-
-    render(){
-        this.renderer.render(this.scene, this.camera)
-    }
-    
-    setDisplay(state){
-        this.show = !!state;
-        if(this.show){
-            this.update() 
-            this.dom.fadeIn(100) 
-        }else{
-            this.dom.fadeOut(100)
-        }  
-         
-    }
-    
-    
-    autoJudgeDisplay(){
-         
-    }
-    
-    
-    
-    setDomPos(){
-        if(!this.viewport)return
-        let right = this.viewport.left + this.viewport.width
-        this.dom.css({'right':((1-right)*100 + 1) + '%'})
-         
-    }
-    
-}
-
-
-export default Compass;

+ 0 - 229
src/objects/tool/CurveCtrl.js

@@ -1,229 +0,0 @@
-
-
- 
-import * as THREE from "../../../libs/three.js/build/three.module.js";
-import {LineDraw} from "../../utils/DrawUtil.js";
-import math  from "../../utils/math.js";
-import HandleSvg from  "./HandleSvg.js";
-import HandleSprite from  "./HandleSprite.js";
-
-const sphere = new THREE.Mesh(new THREE.SphereBufferGeometry(0.08,0.08,3,2), new THREE.MeshBasicMaterial({color:'#f88'}))
-
-
-
-export default class CurveCtrl extends THREE.Object3D {
-    
-    constructor(points, lineMat, color, name, options={}){
-        super()
-        this.curve = new THREE.CatmullRomCurve3(points, false, "centripetal"    /* , tension */)
-        this.name = name || 'curveNode'
-        this.handleMat = options.handleMat
-        this.lineMat = lineMat
-        this.createPath(); 
-        this.color = color;
-        this.handles = []; 
-        this.wholeLength = 0 
-        this.viewports = options.viewports || [viewer.mainViewport] //for HandleSprite
-        for(let i=0,j=this.points.length; i<j;i++){
-            this.handles.push(this.createHandle(this.points[i]))
-        }   
-        this.visible_ = true
-        
-         
-        
-        if(Potree.settings.isTest){   
-            this.spheres = new THREE.Object3D;
-            /* let i = Count+1;
-            while(i>0){
-                this.spheres.add(sphere.clone());
-                i--;
-            } */
-            this.add(this.spheres)
-        }
-        
-        this.updatePath()
-        
-        
-    }
-    
-    
-    addPoint(position, index, ifUpdate){
-        let length = this.points.length 
-        
-        if(index == void 0 ){
-			index = length;
-		}
-        
-        let handle = this.createHandle(position);
-         
-        this.handles = [...this.handles.slice(0,index), handle, ...this.handles.slice(index,length)]
-      
-        this.points = [...this.points.slice(0,index), position, ...this.points.slice(index,length)]
-        
-        ifUpdate && (this.updatePath(), this.updateHandle(index))
-    
-    }
-    removePoint(index){
-        let handle = this.handles[index]
-        handle.dispose();
-        
-        this.handles.splice(index,1)
-        this.points.splice(index,1)
-        this.updatePath()
-    }
-    
-    createPath(){ 
-   
-        const line = LineDraw.createFatLine( [ ],this.lineMat)
-        this.line = line;
-        this.add(line);
-    }
-    
-    
-    updatePath(){ 
-        this.curve.needsUpdate = true; //如果不更新,得到的点不均匀,开头点少。 
-        
-        let points, length = this.points.length
-        
-        this.wholeLength = this.points.reduce((total, currentValue, currentIndex, arr)=>{ //所有端点的距离总和
-            if(currentIndex == 0)return 0
-            return total + currentValue.distanceTo(arr[currentIndex-1]);
-        },0)
-        
-        if(length > 1){ 
-            const count = THREE.Math.clamp(Math.ceil(this.wholeLength * 5), 30, 500);
-         
-            points = this.curve.getSpacedPoints( count ); 
-              
-              
-            if(this.needsPercent){ //获取每个节点在整条中的百分比,便于定位(但不精确)
-                this.pointsPercent = [0];
-                let sums = [0]
-                let sum = 0, last = points[0]
-                for(let i=1;i<length;i++){
-                    let point = this.points[i];
-                    sum += point.distanceTo(last);  //参考getLengths函数,根据长度得到百分比
-                    last = point;
-                    sums.push(sum) 
-                }
-                for(let i=1;i<length;i++){
-                    this.pointsPercent.push(sum == 0 ? i/length : sums[i] / sum);
-                }
-                
-                
-            }
-              
-            
-              
-              
-              
-            if(Potree.settings.isTest){
-                this.spheres.children.forEach(e=>e.visible = false);
-                points.forEach((e,i)=>{
-                    let sphere1 = this.spheres.children[i]
-                    if(!sphere1){
-                        sphere1 = sphere.clone();
-                        this.spheres.add(sphere1);
-                    }                        
-                    sphere1.position.copy(e)
-                    sphere1.visible = true
-                })
-            }
-        }else{
-            points = []
-        } 
-        
-        
-        LineDraw.updateLine(this.line, points)      
-        
-        
-        this.dispatchEvent('updatePath')
-        
-    }
-    
-    
-    createHandle(position){
-        if(this.handleMat){
-            var handle = new HandleSprite(position,  {mat:this.handleMat, viewports:this.viewports})
-            this.add(handle)
-        }else{
-            var handle = new HandleSvg(position,  this.color)
-        }
-		
-        handle.visible = this.visible 
-        handle.addEventListener('dragged',(e)=>{
-            let index = this.handles.indexOf(handle) 
-            this.points[index].copy(e.position) 
-            
-            this.updatePath()
-            
-            this.dispatchEvent({type:'dragCurvePoint', index})
-        })
-        
-        return handle
-	}
-    
-    
-    
-    updateHandle(index){
-        if(!this.visible)return
-        
-        this.handles[index].update() 
-            
-    }
-    
-    updateHandles(){
-        
-        this.handles.forEach((handle,index)=>{
-            this.updateHandle(index) 
-        }) 
-    }
-    
-    update(){
-        this.updateHandles()
-        this.updatePath()
-    }
-    
-    set visible(v){ 
-        if(v != this.visible_ ){
-            this.visible_ = v 
-            this.visible = v 
-            if(this.handles){ 
-                this.handles.forEach(e=>e.visible = v  )
-                if(v) this.updateHandles() //因为不可见时没更新位置
-            }
-        }
-    }
-    get visible(){
-        return this.visible_
-    }  
-    
-    
-    /* set visible(v){ 
-        this.handles.forEach(e=>e.svg.style.display = v ? "" : "none" )
-        if(v) this.updateHandles() //因为不可见时没更新位置
-    } */
-    get points(){
-        return this.curve.points;
-    }
-    set points(points){
-        this.curve.points = points
-    }
-    getPointAt(t){
-        return this.curve.getPointAt(t)
-    }
-    getSpacedPoints(t){
-        return this.curve.getSpacedPoints(t)
-    }
-    dispose(){
-        this.parent && this.parent.remove(this);
-        
-        this.handles.forEach(e=>e.dispose() )
-        
-        this.line.geometry && this.line.geometry.dispose()
-        
-    }
-    
-    
-    
-}

+ 0 - 78
src/objects/tool/HandleSprite.js

@@ -1,78 +0,0 @@
-import * as THREE from "../../../libs/three.js/build/three.module.js";
-import Sprite from  "../Sprite.js";
-/* 
-两种拖拽方式:
-1 只依附在点云上
-2 平行于镜头view移动 */
-
-
-
-
-
-
-const geo = new THREE.PlaneBufferGeometry(1,1)
-export default class HandleSprite extends Sprite{
-    constructor(position,options={}){
-        
-        options.sizeInfo = {width2d:60} 
-        super(options)
-        this.position.copy(position);
-         
-        this.dragStyle =  options.dragStyle || 'default'    //'default'||'onPointCloud'  
-        
-        
-        this.bindEvent()
-        
-        
-    }
-    
-    
-    bindEvent(){
-        let projectedStart, pointerStart
-        
-        const drag = (e)=>{ 
-            /* if(e.hoverViewport != e.drag.dragViewport){//不能使用e.dragViewport,要使用drag中的,因为drag中存储的要一直继承下来,不因mouseup了而改变。
-                viewer.dispatchEvent({
-                    type : "CursorChange", action : "add",  name:"polygon_AtWrongPlace"
-                })
-                return
-            } */ 
-            const camera = viewer.scene.getActiveCamera();
-            if(projectedStart){
-                let move2d = new THREE.Vector2().subVectors(e.pointer, pointerStart)
-                let projectNow = projectedStart.clone()
-                projectNow.x += move2d.x;
-                projectNow.y += move2d.y; 
-                let unprojected = projectNow.clone().unproject(camera);
-                this.position.set(unprojected.x, unprojected.y, unprojected.z);
-            }else{
-                projectedStart = this.position.clone().project(camera);
-                pointerStart = e.pointer.clone()
-            }
-             
-            this.update()
-            this.dispatchEvent({type:'dragged', position: this.position }) 
-        }
-        
-        const drop = (e)=>{
-            projectedStart = null, pointerStart = null
-        }
-        
-        const mouseover = (e) => {  
-            viewer.dispatchEvent({
-                type : "CursorChange", action : "add",  name:"markerMove"
-            }) 
-        };
-        const mouseleave = (e) => {  
-            viewer.dispatchEvent({
-                type : "CursorChange", action : "remove",  name:"markerMove"
-            })
-        } 
-        
-        this.addEventListener('drag', drag) 
-        this.addEventListener('drop', drop)  
-        this.addEventListener('mouseover', mouseover);
-        this.addEventListener('mouseleave', mouseleave);
-    }
-    
-}

+ 0 - 155
src/objects/tool/HandleSvg.js

@@ -1,155 +0,0 @@
-
-import math  from "../../utils/math.js";
- 
-import * as THREE from "../../../libs/three.js/build/three.module.js";
-import {ExtendEventDispatcher} from "../../custom/ExtendEventDispatcher.js";
- 
-export default class HandleSvg extends ExtendEventDispatcher{
-    constructor(position, color){
-        super()
-        this.position = position
-		this.color = '#'+new THREE.Color(color).getHexString()
-        this.svg = this.create() 
-        this.visible_ = true  
-        
-        let update = ()=>{
-            this.update()
-        }
-        viewer.addEventListener("camera_changed", update)
-        
-        this.addEventListener('dispose', ()=>{ 
-            viewer.removeEventListener("camera_changed",  update)  
-        })
-    }
-    
-    
-    create(){
-        
-        const svgns = "http://www.w3.org/2000/svg";
-		const svg = document.createElementNS(svgns, "svg");
-
-		svg.setAttribute("width", "2em");
-		svg.setAttribute("height", "2em");
-		svg.setAttribute("position", "absolute");
-
-		svg.style.left = "50px";
-		svg.style.top = "50px";
-		svg.style.position = "absolute";
-		svg.style.zIndex = "10000";
-        svg.style.cursor = 'grab'
-        svg.style.transform = 'translate(-50%,-50%)'
-        
-		const circle = document.createElementNS(svgns, 'circle');
-		circle.setAttributeNS(null, 'cx', "1em");
-		circle.setAttributeNS(null, 'cy', "1em");
-		circle.setAttributeNS(null, 'r', "0.5em");
-		circle.setAttributeNS(null, 'style', 'fill: '+this.color+'; stroke: black; stroke-width: 0.2em;' );
-		svg.appendChild(circle);
-         
-		const element = viewer.renderer.domElement.parentElement;
-		element.appendChild(svg);
-
-
-		const startDrag = (evt) => {
-            /* if(evt.button === THREE.MOUSE.RIGHT){
-                return
-            } */
-			this.selectedElement = svg;
-
-			document.addEventListener("mousemove", drag);
-		};
-
-		const endDrag = (evt) => {
-			this.selectedElement = null;
-
-			document.removeEventListener("mousemove", drag);
-		};
-
-		const drag = (evt) => {
-			if (this.selectedElement) {
-                 
-				evt.preventDefault();
-
-				const rect = viewer.renderer.domElement.getBoundingClientRect();
-
-				const x = evt.clientX - rect.x;
-				const y = evt.clientY - rect.y;
-
-				const {width, height} = viewer.renderer.getSize(new THREE.Vector2());
-				const camera = viewer.scene.getActiveCamera();
-				 
-                const projected = this.position.clone().project(camera);
-          
-
-				projected.x = ((x / width) - 0.5) / 0.5;
-				projected.y = (-(y - height) / height - 0.5) / 0.5;
-
-				const unprojected = projected.clone().unproject(camera);
-				this.position.set(unprojected.x, unprojected.y, unprojected.z);
-                
-                this.update()
-                this.dispatchEvent({type:'dragged', position: this.position})
-                
-			}
-		};
-
-		svg.addEventListener('mousedown', startDrag);
-		svg.addEventListener('mouseup', endDrag);
-        svg.style.display = this.visible ? "" : "none" 
-         
-        
-        this.addEventListener('dispose',()=>{
-            svg.removeEventListener('mousedown', startDrag);
-            svg.removeEventListener('mouseup', endDrag); 
-        })
-        
-        
-        
-        return svg
-    }
-    
-    
-    
-   
-   
-    set visible(v){
-        this.visible_ = v  
-        if(v){
-            this.update()
-        }else{
-            this.svg.style.display = "none"
-        } 
-    }
-    get visible(){
-        return this.visible_ 
-    }
-   
-   
-    update(){
-        if(!this.visible)return
-        
-        let camera = viewer.scene.getActiveCamera() 
-          
-        
-        var p = Potree.Utils.getPos2d( this.position, camera , viewer.renderArea, viewer.mainViewport);
-        if(!p.trueSide){
-            return this.svg.style.display = 'none'; 
-        }
-        this.svg.style.left =  p.posInViewport.x  
-        this.svg.style.top = p.posInViewport.y 
-          
-        
-         
-        this.svg.style.display = ''
-            
-    }
-    
-    
-    
-    dispose(){
-        this.svg.remove()
-        this.dispatchEvent('dispose')
-    }
-}
-
- 	

File diff suppressed because it is too large
+ 0 - 1245
src/objects/tool/Measure.js


+ 0 - 646
src/objects/tool/MeasuringTool.js

@@ -1,646 +0,0 @@
-
-import * as THREE from "../../../libs/three.js/build/three.module.js";
-import {Measure} from "./Measure.js";
-import {Utils} from "../../utils.js"; 
-import math from "../../utils/math.js";
-import {CameraMode} from "../../defines.js"; 
-import {TextSprite} from '../TextSprite.js'
-import {ExtendEventDispatcher} from "../../custom/ExtendEventDispatcher.js";
- 
- 
- 
-function updateAzimuth(viewer, measure){
-    if(!measure.showAzimuth)return
-	const azimuth = measure.azimuth;
-
-	const isOkay = measure.points.length === 2;
-
-	azimuth.node.visible = isOkay  
-
-	if(!azimuth.node.visible){
-		return;
-	}
-
-	const camera = viewer.scene.getActiveCamera();
-	const renderAreaSize = viewer.renderer.getSize(new THREE.Vector2());
-	const width = renderAreaSize.width;
-	const height = renderAreaSize.height;
-	
-	const [p0, p1] = measure.points;
-	const r = p0.position.distanceTo(p1.position);
-	const northVec = Utils.getNorthVec(p0.position, r, viewer.getProjection());
-	const northPos = p0.position.clone().add(northVec);
-
-	azimuth.center.position.copy(p0.position);
-	azimuth.center.scale.set(2, 2, 2);
-	
-	azimuth.center.visible = false;
-	// azimuth.target.visible = false;
-
-
-	{ // north
-		azimuth.north.position.copy(northPos);
-		azimuth.north.scale.set(2, 2, 2);
-
-		let distance = azimuth.north.position.distanceTo(camera.position);
-		let pr = Utils.projectedRadius(1, camera, distance, width, height);
-
-		let scale = (5 / pr);
-		azimuth.north.scale.set(scale, scale, scale);
-	}
-
-	{ // target
-		azimuth.target.position.copy(p1.position);
-		azimuth.target.position.z = azimuth.north.position.z;
-
-		let distance = azimuth.target.position.distanceTo(camera.position);
-		let pr = Utils.projectedRadius(1, camera, distance, width, height);
-
-		let scale = (5 / pr);
-		azimuth.target.scale.set(scale, scale, scale);
-	}
-
- 
-	azimuth.circle.position.copy(p0.position);
-	azimuth.circle.scale.set(r, r, r);
-	azimuth.circle.material.resolution.set(width, height);
-
-	// to target
-	azimuth.centerToTarget.geometry.setPositions([
-		0, 0, 0,
-		...p1.position.clone().sub(p0.position).toArray(),
-	]);
-	azimuth.centerToTarget.position.copy(p0.position);
-	azimuth.centerToTarget.geometry.verticesNeedUpdate = true;
-	azimuth.centerToTarget.geometry.computeBoundingSphere();
-	azimuth.centerToTarget.computeLineDistances();
-	azimuth.centerToTarget.material.resolution.set(width, height);
-
-	// to target ground
-	azimuth.centerToTargetground.geometry.setPositions([
-		0, 0, 0,
-		p1.position.x - p0.position.x,
-		p1.position.y - p0.position.y,
-		0,
-	]);
-	azimuth.centerToTargetground.position.copy(p0.position);
-	azimuth.centerToTargetground.geometry.verticesNeedUpdate = true;
-	azimuth.centerToTargetground.geometry.computeBoundingSphere();
-	azimuth.centerToTargetground.computeLineDistances();
-	azimuth.centerToTargetground.material.resolution.set(width, height);
-
-	// to north
-	azimuth.centerToNorth.geometry.setPositions([
-		0, 0, 0,
-		northPos.x - p0.position.x,
-		northPos.y - p0.position.y,
-		0,
-	]);
-	azimuth.centerToNorth.position.copy(p0.position);
-	azimuth.centerToNorth.geometry.verticesNeedUpdate = true;
-	azimuth.centerToNorth.geometry.computeBoundingSphere();
-	azimuth.centerToNorth.computeLineDistances();
-	azimuth.centerToNorth.material.resolution.set(width, height);
-
-	// label
-	const radians = Utils.computeAzimuth(p0.position, p1.position, viewer.getProjection());
-	let degrees = THREE.Math.radToDeg(radians);
-	if(degrees < 0){
-		degrees = 360 + degrees;
-	}
-	const txtDegrees = `${degrees.toFixed(2)}°`;
-	const labelDir = northPos.clone().add(p1.position).multiplyScalar(0.5).sub(p0.position);
-	if(labelDir.length() > 0){
-		labelDir.z = 0;
-		labelDir.normalize();
-		const labelVec = labelDir.clone().multiplyScalar(r);
-		const labelPos = p0.position.clone().add(labelVec);
-		azimuth.label.position.copy(labelPos);
-	}
-	azimuth.label.setText(txtDegrees);
-	let distance = azimuth.label.position.distanceTo(camera.position);
-	let pr = Utils.projectedRadius(1, camera, distance, width, height);
-	let scale = (70 / pr);
-	azimuth.label.scale.set(scale, scale, scale);
-}
-
-export class MeasuringTool extends ExtendEventDispatcher{
-	constructor (viewer) {
-		super();
-
-		this.viewer = viewer;
-		this.renderer = viewer.renderer;
-
-		this.viewer.addEventListener('start_inserting_measurement', e => {
-			this.viewer.dispatchEvent({
-				type: 'cancel_insertions'
-			});
-		});
-
-		this.showLabels = true;
-        this.scene = new THREE.Scene();
-		this.scene.name = 'scene_measurement';
-		//this.light = new THREE.PointLight(0xffffff, 1.0);
-		//this.scene.add(this.light);  
-		this.viewer.inputHandler.registerInteractiveScene(this.scene);
-		  
-        
-        //this.scene = viewer.overlay//
-        
-        
-		this.onRemove = (e) => { e.measurement.dispose()/* this.scene.remove(e.measurement); */};
-		this.onAdd = e => {this.scene.add(e.measurement);};
-
-		for(let measurement of viewer.scene.measurements){
-			this.onAdd({measurement: measurement});
-		}
-		 
-        viewer.addEventListener('camera_changed',(e)=>{ 
-            if(e.viewport == viewer.mainViewport ) this.update()
-        })
-        
-        
-		//viewer.addEventListener("update", this.update.bind(this));
-		viewer.addEventListener("render.pass.perspective_overlay", this.render.bind(this));
-		viewer.addEventListener("scene_changed", this.onSceneChange.bind(this));
-
-		viewer.scene.addEventListener('measurement_added', this.onAdd);
-		viewer.scene.addEventListener('measurement_removed', this.onRemove);
-        
-        viewer.addEventListener('resize',this.setSize.bind(this))
-        
-	}
-
-	onSceneChange(e){
-		if(e.oldScene){
-			e.oldScene.removeEventListener('measurement_added', this.onAdd);
-			e.oldScene.removeEventListener('measurement_removed', this.onRemove);
-		}
-
-		e.scene.addEventListener('measurement_added', this.onAdd);
-		e.scene.addEventListener('measurement_removed', this.onRemove);
-	}
-
-
-    
-
-
-    
-    createMeasureFromData(data){//add 
-    
-        const measure = new Measure(data);
-        if(measure.failBuilded){
-            return 
-        }
-        viewer.scene.addMeasurement(measure);
-        
-        if(measure.guideLine)measure.guideLine.visible = false
-        return  measure       
-    }
-    
-    
-	update(){
-        return;
-        
-        
-        
-        
-		let camera = this.viewer.scene.getActiveCamera();
-		let domElement = this.renderer.domElement;
-		let measurements = this.viewer.scene.measurements;
-
-	 
-		// make size independant of distance
-        let mainLabels = [], subLabels = [];
-        
-      
-        
-		for (let measure of measurements) {
-			measure.lengthUnit = this.viewer.lengthUnit;
-			measure.lengthUnitDisplay = this.viewer.lengthUnitDisplay;
-			//measure.update();
-
-			updateAzimuth(this.viewer, measure);
-
-			 
-            /*  [...measure.markers, ...measure.edgeLabels, measure.areaLabel].forEach(e=>{
-                e && e.update() 
-            }); */
-             
-
-			// labels
-			/* let labels = measure.edgeLabels.concat(measure.angleLabels);
-			for(let label of labels){ 
-                label.update()
-                if(label.elem.hasClass('sub')){
-                    subLabels.push(label)
-                }else{ 
-                    mainLabels.push(label)
-                }
-			}
-
-			// coordinate labels
-			for (let j = 0; j < measure.coordinateLabels.length; j++) { 
-				let label = measure.coordinateLabels[j]; 
-                label.update() 
-                mainLabels.push(label)
-			} 
- 
-
-			if(measure.showArea){ // area label
-				let label = measure.areaLabel; 
-                label.update()
-                mainLabels.push(label)
-			} */
-             
-            
-
-			/* if(measure.showCircle){ // radius label
-				let label = measure.circleRadiusLabel;
-				let distance = label.position.distanceTo(camera.position);
-				let pr = Utils.projectedRadius(1, camera, distance, clientWidth, clientHeight);
-
-				let scale = (70 / pr);
-				label.scale.set(scale, scale, scale);
-			} */ 
-			if(!this.showLabels){ 
-				const labels = [
-					...measure.sphereLabels,  
-					...measure.angleLabels,  
-					measure.circleRadiusLabel,
-				]; 
-				for(const label of labels){
-					label.visible = false;
-				}
-			}
-		}
-        //this.updateLabelZIndex([{labels:subLabels},{labels:mainLabels}])
-        
-	}
-    setSize(e){ //e.resolution
-        /* if(Measure.lineMats){
-            for(var m in Measure.lineMats){
-                Measure.lineMats[m].resolution.set(e.canvasWidth, e.canvasHeight);
-            }  
-        }  
-        if(Measure.sphereMats){
-            for(var s in Measure.sphereMats){
-                Measure.sphereMats[s].uniforms.resolution.value.set(e.canvasWidth, e.canvasHeight);
-            }
-        }
-        for (let measure of this.viewer.scene.measurements) { 
-            measure.edgeLabels.concat(measure.areaLabel).forEach(label=>{ 
-                label.sprite.material.uniforms.resolution.value.set(e.canvasWidth, e.canvasHeight);
-            })
-        } */
-    }
-    
-    updateLabelZIndex(group){//[{labels:[]},{}] 顺序按照z-index低到高
-        
-        group.forEach((e,i)=>{
-            e.base = group[i-1] ? group[i-1].base + group[i-1].labels.length : 0
-         
-            var labels = e.labels.sort((a,b)=>{
-                return b.pos2d.z - a.pos2d.z
-            }) 
-            labels.forEach((label,index)=>{
-                $(label.elem).css('z-index', e.base+index) 
-            }) 
-        }) 
-        
-    }
-    
-    
-    
-    
-    editStateChange(e){
-        //console.log("editStateChange" , e.state)
-        let state = e.state
-        if(!state){
-            state = viewer.scene.measurements.some(e=>e.isEditing)
-        }
-        
-        if(state){
-            viewer.dispatchEvent({type:"measureMovePoint"})
-        }else{
-            viewer.dispatchEvent({type:"endMeasureMove"})
-        }
-        
-        
-        //this.editing = 
-    }
-    
-    
-    
-	startInsertion (args = {}, callback, cancelFun) {
-        
-        
-		let domElement = this.viewer.renderer.domElement;
-
-		
-
-		const pick = (defaul, alternative) => {
-			if(defaul != null){
-				return defaul;
-			}else{
-				return alternative;
-			}
-		};
-
-		args.showDistances = (args.showDistances === null) ? true : args.showDistances;
-
-		args.showArea = pick(args.showArea, false);
-		args.showAngles = pick(args.showAngles, false);
-		args.showCoordinates = pick(args.showCoordinates, false);
-		args.showHeight = pick(args.showHeight, false);
-		args.showCircle = pick(args.showCircle, false);
-		args.showAzimuth = pick(args.showAzimuth, false);
-		args.showEdges = pick(args.showEdges, true);
-		args.closed = pick(args.closed, false);
-		args.maxMarkers = pick(args.maxMarkers, Infinity);
-        args.direction = args.direction//add
-		args.type = args.type    /*  || 'Measurement'; */
-        args.showGuideLine = pick(args.showGuideLine, false);  
-        args.isRect = pick(args.isRect, false);
-        
- 
-        let measure = new Measure(args);
-        this.scene.add(measure);
-        measure.isNew = true
-        
-        
-		this.viewer.dispatchEvent({
-			type: 'start_inserting_measurement',
-			measure: measure
-		});
-         
-        measure.addEventListener('editStateChange', this.editStateChange.bind(this))
-        measure.editStateChange(true)
-        
-        let timer;
-
- 
-
-		let endDragFun = (e) => { 
-            let length = measure.points.length
-			if (e.button == THREE.MOUSE.LEFT || e.isTouch) { 
-				if (length >= measure.maxMarkers) {
-                    end({finish:true});
-				}else{  
-                    var marker = measure.addMarker({point:measure.points[length - 1].clone()})
-                     
-                    if(args.isRect && measure.markers.length == 3){//marker全可见
-                        measure.addMarker({point:measure.points[0].clone()})
-                        
-                    }else{ 
-                        measure.markers[length].visible = false
-                        measure.edges[length].visible = false 
-                    }
-                    measure.edges[length-1].visible = true 
-                    
-                    measure.markers[length-1].visible = true;
-                    
-                    measure.editStateChange(true) //重新激活reticule状态
-                    
-                    marker.isDragging = true 
-                    measure.continueDrag(marker, e)    
-                } 
-				 
-			} else if (e.button === THREE.MOUSE.RIGHT ) { //触屏怎么取消?
-				if(e.pressDistance < Potree.config.clickMaxDragDis )end(e);//非拖拽的话
-                else measure.continueDrag(null, e)     
-                 
-			}
-		};
-
-		let end = (e={}) => {//确定、结束
-            if(!measure.isNew)return
-            if(args.minMarkers != void 0){
-                if(!e.finish && measure.markers.length<=args.minMarkers){//右键  当个数不够时取消
-                    //this.viewer.scene.removeMeasurement(measure)
-                    //cancelFun && cancelFun()
-                    //重新开始画
-                    measure.markers[0].removeEventListener('mousedown',end)
-                    measure.reDraw()
-                     
-                    
-                    this.viewer.addEventListener('global_click', click, 10)
-                   
-                    measure.editStateChange(true)
-                    return
-                    
-                    /* if(!Potree.settings.isOfficial) this.viewer.scene.removeMeasurement(measure)
-                    else if(e.drag){ //正式版本不允许右键退出, 继续
-                        continueDrag(e.drag.object)
-                        measure.editStateChange(true)
-                        return
-                    } */
-                } 
-            }
-            if (/* !e.finish &&  */measure.markers.length > 3) {
-				measure.removeMarker(measure.points.length - 1); 
-                measure.markers[0].removeEventListener('mouseover', mouseover);
-                measure.markers[0].removeEventListener('mouseleave', mouseleave);
-                measure.markers[0].removeEventListener('click'/* 'mousedown' */,Exit) 
-                
-                if(e.byClickMarker && measure.markers.length > 3){//通过点击第一个marker而结束的话,会多一个marker
-                    measure.removeMarker(measure.points.length - 1); 
-                }
-			}
-            measure.isNew = false
-            let length = measure.points.length 
-            if(length){
-                measure.markers[length-1].visible = true; 
-                measure.edges[length-1].visible = true  
-                
-                measure.markers.forEach(marker=>{marker.dispatchEvent('addHoverEvent') })
-                measure.edges.forEach(edge=>{edge.dispatchEvent('addHoverEvent') })
-              
-            }
-            clearTimeout(timer) 
-			this.viewer.removeEventListener('cancel_insertions', Exit);
-            //pressExit && this.viewer.inputHandler.removeEventListener('keydown', pressExit);
-            this.viewer.removeEventListener('global_click', click)
-            this.viewer.removeEventListener('global_mousemove', ifAtWrongPlace) 
-            viewer.dispatchEvent({
-                type : "CursorChange", action : "remove",  name:"polygon_AtWrongPlace"
-            });
-            
-            viewer.inputHandler.dispatchEvent({type:'isMeasuring',  v:false, cause:'stopInsertion'}  ) 
-            
-            e.remove || callback && callback()  
-            /* this.viewer.dispatchEvent({
-                type: 'finish_inserting_measurement',
-                measure: measure
-            }); */
-		};
-
-        
-        let Exit = (e)=>{//强制退出
-        
-            if(e.measure && e.measure != measure){
-                return;//若指定了退出的measure但和该measure不一致,就返回
-            }
-            console.log('Exit: ' +  measure.id)
-            if(e.remove){
-                viewer.scene.removeMeasurement(measure)  
-            }
-            
-            measure.editStateChange(false)
-            measure.cannotConfirmNormal = false  //一些dropMarker中的句子
-            measure.guideLine &&(measure.guideLine.visible = false)
-            /*
-            if(this.viewer.inputHandler.drag && !e.remove ){//还未触发drop的话   
-                  this.viewer.inputHandler.drag.object.dispatchEvent({  //这句会导致又增一个marker
-                    type: 'drop',
-                    drag: this.viewer.inputHandler.drag, 
-                    viewer: this.viewer,
-                    pressDistance:0,
-                    button : THREE.MOUSE.RIGHT  
-                }); 
-                 
-            }   else  {*///未结束时添加新的measure时会触发
-                end({finish:true, remove:e.remove, byClickMarker: e.type == 'click'})  
-            //}
-            this.viewer.inputHandler.drag && (this.viewer.inputHandler.drag.object = null)
-            
-        }
-        
-        
-        
-        this.viewer.addEventListener('cancel_insertions', Exit);
-        
-        /*let pressExit
-         if(!Potree.settings.isOfficial){
-            pressExit = (e)=>{ 
-                if(e.keyCode == 27){//Esc
-                    //Exit()
-                    //怎么模拟右键???//现由前端发出
-                }
-            } 
-            this.viewer.inputHandler.addEventListener('keydown', pressExit) 
-        } */ 
-		let mouseover = (e) => { 
-            measure.setMarkerSelected(e.object, 'hover', 'single'); 
-              
-        };
-        let mouseleave = (e) => { 
-            measure.setMarkerSelected(e.object, 'unhover', 'single'); 
-        }  
-          
-                 
-        let click = (e)=>{//一旦点击就立刻增加两marker  
-        
-            if(ifAtWrongPlace(e))return  
-            if(e.clickElement)return  //如点击label时focusOnObject
-             
-            
-            if(e.button === THREE.MOUSE.RIGHT)return 
-            
-            //console.log('measure clicked33', !!e.intersectPoint)
-             
-            //var I = e.intersectPoint && (e.intersectPoint.orthoIntersect || e.intersectPoint.location)
-            var I = e.intersect && (e.intersect.orthoIntersect || e.intersect.location)
-            if(!I){
-                return measure.dispatchEvent('intersectNoPointcloud') 
-            }
-            var atMap = e.drag.dragViewport.name == 'mapViewport'
-            //在地图上测量的首个点按楼层高度(暂时先只按mainViewport相机高度吧,但navvis是按楼层,画在楼层的地面上,可能因为平面图显示的是楼层近地面),
-            
-            if(atMap){ 
-                I = I.clone().setZ(viewer.mainViewport.camera.position.z ) 
-            }
-             
-            var marker = measure.addMarker({point:I})
-            marker.isDragging = true 
-            this.viewer.inputHandler.startDragging(marker , {endDragFun, notPressMouse:true} ); //notPressMouse代表不是通过按下鼠标来拖拽
-            e.drag = this.viewer.inputHandler.drag
-            e.drag.endDragFun = endDragFun
-            e.drag.notPressMouse = true
-            
-            //if(!measure.dragMarker(e) || !measure.dropMarker(e))return
-             
-            measure.dragMarker(e) 
-            measure.dropMarker(e)
-            
-            if(measure.maxMarkers > 1 ){
-                measure.markers[1].visible = false
-                measure.edges[1].visible = false
-            }
-            if(measure.maxMarkers>2 && !measure.isRect){ 
-                measure.markers[0].addEventListener('mouseover', mouseover);
-                measure.markers[0].addEventListener('mouseleave', mouseleave);
-                measure.markers[0].addEventListener('click'/* 'mousedown' */,Exit) //点击到第一个marker就结束 
-            }
-            
-            
-            this.viewer.removeEventListener('global_click', click)///* global_drop */
-            
-            
-            
-            //console.log('measure clicked')
-            e.consume && e.consume()
-            
-            return {stopContinue:true}//防止继续执行别的侦听,如flytopano
-        }
-        
-        //点击第n下拥有n+1个marker, n>0
-        
-        viewer.inputHandler.dispatchEvent({type: 'isMeasuring', v: true, cause:'startInsertion'})
-        
-        this.viewer.addEventListener('global_click', click, 10)//add importance:10
-            
-        let ifAtWrongPlace = (e)=>{
-            if(measure.unableDragAtMap && e.hoverViewport.name == 'mapViewport' ){ 
-                if(e.isTouch){
-                    viewer.dispatchEvent({type:'reticule_forbit', v:true})
-                }else{
-                    viewer.dispatchEvent({
-                        type : "CursorChange", action : "add",  name:"polygon_AtWrongPlace"
-                    });
-                } 
-                return true
-            }else{ 
-                if(e.isTouch){
-                    viewer.dispatchEvent({type:'reticule_forbit',v:false})
-                }else{
-                    viewer.dispatchEvent({
-                        type : "CursorChange", action : "remove",  name:"polygon_AtWrongPlace"
-                    });
-                }
-            }
-        }
-        
-        
-        
-        if(measure.unableDragAtMap){ 
-            this.viewer.addEventListener('global_mousemove', ifAtWrongPlace) 
-        }
-        
-        
-		this.viewer.scene.addMeasurement(measure);
-        
-		return measure;
-	}
-	
-    
-	render(o={}){
-        if(this.scene.children.length == 0)return
-        
-        viewer.setCameraLayers(o.camera, ['measure'])
-		
-        if(o.screenshot && this.viewer.ssaaRenderPass.enabled){ //抗锯齿
-            this.viewer.ssaaRenderPass.sampleLevel = 4
-            this.viewer.composer.render(this.scene, o.camera );  
-            /* viewer.scene.measurements.forEach(e=>{ //隐藏除了label以外的
-                e.children.forEach((c)=>{
-                    if(!(c instanceof TextSprite)){
-                        c.visible = false
-                    } 
-                }) 
-            })  */
-        }else{
-            this.viewer.renderer.render(this.scene, o.camera );
-        }
-	}
-};

+ 0 - 66
src/objects/tool/PolygonClipVolume.js

@@ -1,66 +0,0 @@
-
-import * as THREE from "../../../libs/three.js/build/three.module.js";
-
-export class PolygonClipVolume extends THREE.Object3D{
-	
-	constructor(camera){
-		super();
-
-		this.constructor.counter = (this.constructor.counter === undefined) ? 0 : this.constructor.counter + 1;
-		this.name = "polygon_clip_volume_" + this.constructor.counter;
-
-		this.camera = camera.clone();
-		this.camera.rotation.set(...camera.rotation.toArray()); // [r85] workaround because camera.clone() doesn't work on rotation
-		this.camera.rotation.order = camera.rotation.order;
-		this.camera.updateMatrixWorld();
-		this.camera.updateProjectionMatrix();
-		this.camera.matrixWorldInverse.copy(this.camera.matrixWorld).invert();
-
-		this.viewMatrix = this.camera.matrixWorldInverse.clone();
-		this.projMatrix = this.camera.projectionMatrix.clone();
-
-		// projected markers
-		this.markers = [];
-		this.initialized = false;
-	}
-
-	addMarker() {
-
-		let marker = new THREE.Mesh();
-
-		let cancel;
-
-		let drag = e => {
-			let size = e.viewer.renderer.getSize(new THREE.Vector2());
-			let projectedPos = new THREE.Vector3(
-				2.0 * (e.drag.end.x / size.width) - 1.0,
-				-2.0 * (e.drag.end.y / size.height) + 1.0,
-				0
-			);
-
-			marker.position.copy(projectedPos);
-		};
-		
-		let drop = e => {	
-			cancel();
-		};
-		
-		cancel = e => {
-			marker.removeEventListener("drag", drag);
-			marker.removeEventListener("drop", drop);
-		};
-		
-		marker.addEventListener("drag", drag);
-		marker.addEventListener("drop", drop);
-
-
-		this.markers.push(marker);
-	}
-
-	removeLastMarker() {
-		if(this.markers.length > 0) {
-			this.markers.splice(this.markers.length - 1, 1);
-		}
-	}
-
-};

+ 0 - 344
src/objects/tool/Profile.js

@@ -1,344 +0,0 @@
-
-import * as THREE from "../../../libs/three.js/build/three.module.js";
-import {Utils} from "../../utils.js";
-
-export class Profile extends THREE.Object3D{
-
-	constructor () {
-		super();
-
-		this.constructor.counter = (this.constructor.counter === undefined) ? 0 : this.constructor.counter + 1;
-
-		this.name = 'Profile_' + this.constructor.counter;
-		this.points = [];
-		this.spheres = [];
-		this.edges = [];
-		this.boxes = [];
-		this.width = 1;
-		this.height = 20;
-		this._modifiable = true;
-
-		this.sphereGeometry = new THREE.SphereGeometry(0.4, 10, 10);
-		this.color = new THREE.Color(0xff0000);
-		this.lineColor = new THREE.Color(0xff0000);
-	}
-
-	createSphereMaterial () {
-		let sphereMaterial = new THREE.MeshLambertMaterial({
-			//shading: THREE.SmoothShading,
-			color: 0xff0000,
-			depthTest: false,
-			depthWrite: false}
-		);
-
-		return sphereMaterial;
-	};
-
-	getSegments () {
-		let segments = [];
-
-		for (let i = 0; i < this.points.length - 1; i++) {
-			let start = this.points[i].clone();
-			let end = this.points[i + 1].clone();
-			segments.push({start: start, end: end});
-		}
-
-		return segments;
-	}
-
-	getSegmentMatrices () {
-		let segments = this.getSegments();
-		let matrices = [];
-
-		for (let segment of segments) {
-			let {start, end} = segment;
-
-			let box = new THREE.Object3D();
-            let length 
-
-
-            if(window.axisYup){
-                length = start.clone().setY(0).distanceTo(end.clone().setY(0));
-                box.scale.set(length, 10000, this.width); //???
-
-            }else{
-                length = start.clone().setZ(0).distanceTo(end.clone().setZ(0));
-                box.scale.set(length, 10000, this.width);  
-                box.up.set(0, 0, 1);
-
-            }
-
-
-
-
-			let center = new THREE.Vector3().addVectors(start, end).multiplyScalar(0.5);
-			let diff = new THREE.Vector3().subVectors(end, start);
-			let target = new THREE.Vector3(diff.y, -diff.x, 0);
-
-			box.position.set(0, 0, 0);
-			box.lookAt(target);
-			box.position.copy(center);
-
-			box.updateMatrixWorld();
-			matrices.push(box.matrixWorld);
-		}
-
-		return matrices;
-	}
-
-	addMarker (point) {
-		this.points.push(point);
-
-		let sphere = new THREE.Mesh(this.sphereGeometry, this.createSphereMaterial());
-
-		this.add(sphere);
-		this.spheres.push(sphere);
-
-		// edges & boxes
-		if (this.points.length > 1) {
-			let lineGeometry = new THREE.Geometry();
-			lineGeometry.vertices.push(new THREE.Vector3(), new THREE.Vector3());
-			lineGeometry.colors.push(this.lineColor, this.lineColor, this.lineColor);
-			let lineMaterial = new THREE.LineBasicMaterial({
-				vertexColors: THREE.VertexColors,
-				lineWidth: 2,
-				transparent: true,
-				opacity: 0.4
-			});
-			lineMaterial.depthTest = false;
-			let edge = new THREE.Line(lineGeometry, lineMaterial);
-			edge.visible = false;
-
-			this.add(edge);
-			this.edges.push(edge);
-
-			let boxGeometry = new THREE.BoxGeometry(1, 1, 1);
-			let boxMaterial = new THREE.MeshBasicMaterial({color: 0xff0000, transparent: true, opacity: 0.2});
-			let box = new THREE.Mesh(boxGeometry, boxMaterial);
-			box.visible = false;
-
-			this.add(box);
-			this.boxes.push(box);
-		}
-
-		{ // event listeners
-			let drag = (e) => {
-				let I = Utils.getMousePointCloudIntersection(
-					e.drag.end, 
-					e.viewer.scene.getActiveCamera(), 
-					e.viewer, 
-					e.viewer.scene.pointclouds);
-
-				if (I) {
-					let i = this.spheres.indexOf(e.drag.object);
-					if (i !== -1) {
-						this.setPosition(i, I.location);
-						//this.dispatchEvent({
-						//	'type': 'marker_moved',
-						//	'profile': this,
-						//	'index': i
-						//});
-					}
-				}
-			};
-
-			let drop = e => {
-				let i = this.spheres.indexOf(e.drag.object);
-				if (i !== -1) {
-					this.dispatchEvent({
-						'type': 'marker_dropped',
-						'profile': this,
-						'index': i
-					});
-				}
-			};
-
-			let mouseover = (e) => e.object.material.emissive.setHex(0x888888);
-			let mouseleave = (e) => e.object.material.emissive.setHex(0x000000);
-
-			sphere.addEventListener('drag', drag);
-			sphere.addEventListener('drop', drop);
-			sphere.addEventListener('mouseover', mouseover);
-			sphere.addEventListener('mouseleave', mouseleave);
-		}
-
-		let event = {
-			type: 'marker_added',
-			profile: this,
-			sphere: sphere
-		};
-		this.dispatchEvent(event);
-
-		this.setPosition(this.points.length - 1, point);
-	}
-
-	removeMarker (index) {
-		this.points.splice(index, 1);
-
-		this.remove(this.spheres[index]);
-
-		let edgeIndex = (index === 0) ? 0 : (index - 1);
-		this.remove(this.edges[edgeIndex]);
-		this.edges.splice(edgeIndex, 1);
-		this.remove(this.boxes[edgeIndex]);
-		this.boxes.splice(edgeIndex, 1);
-
-		this.spheres.splice(index, 1);
-
-		this.update();
-
-		this.dispatchEvent({
-			'type': 'marker_removed',
-			'profile': this
-		});
-	}
-
-	setPosition (index, position) {
-		let point = this.points[index];
-		point.copy(position);
-
-		let event = {
-			type: 'marker_moved',
-			profile:	this,
-			index:	index,
-			position: point.clone()
-		};
-		this.dispatchEvent(event);
-
-		this.update();
-	}
-
-	setWidth (width) {
-		this.width = width;
-
-		let event = {
-			type: 'width_changed',
-			profile:	this,
-			width:	width
-		};
-		this.dispatchEvent(event);
-
-		this.update();
-	}
-
-	getWidth () {
-		return this.width;
-	}
-
-	update () {
-		if (this.points.length === 0) {
-			return;
-		} else if (this.points.length === 1) {
-			let point = this.points[0];
-			this.spheres[0].position.copy(point);
-
-			return;
-		}
-
-		let min = this.points[0].clone();
-		let max = this.points[0].clone();
-		let centroid = new THREE.Vector3();
-		let lastIndex = this.points.length - 1;
-		for (let i = 0; i <= lastIndex; i++) {
-			let point = this.points[i];
-			let sphere = this.spheres[i];
-			let leftIndex = (i === 0) ? lastIndex : i - 1;
-			// let rightIndex = (i === lastIndex) ? 0 : i + 1;
-			let leftVertex = this.points[leftIndex];
-			// let rightVertex = this.points[rightIndex];
-			let leftEdge = this.edges[leftIndex];
-			let rightEdge = this.edges[i];
-			let leftBox = this.boxes[leftIndex];
-			// rightBox = this.boxes[i];
-
-			// let leftEdgeLength = point.distanceTo(leftVertex);
-			// let rightEdgeLength = point.distanceTo(rightVertex);
-			// let leftEdgeCenter = new THREE.Vector3().addVectors(leftVertex, point).multiplyScalar(0.5);
-			// let rightEdgeCenter = new THREE.Vector3().addVectors(point, rightVertex).multiplyScalar(0.5);
-
-			sphere.position.copy(point);
-
-			if (this._modifiable) {
-				sphere.visible = true;
-			} else {
-				sphere.visible = false;
-			}
-
-			if (leftEdge) {
-				leftEdge.geometry.vertices[1].copy(point);
-				leftEdge.geometry.verticesNeedUpdate = true;
-				leftEdge.geometry.computeBoundingSphere();
-			}
-
-			if (rightEdge) {
-				rightEdge.geometry.vertices[0].copy(point);
-				rightEdge.geometry.verticesNeedUpdate = true;
-				rightEdge.geometry.computeBoundingSphere();
-			}
-
-			if (leftBox) {
-				let start = leftVertex;
-				let end = point;
-                let length
-
-                if(window.axisYup){
-                    length = start.clone().setY(0).distanceTo(end.clone().setY(0));
-                }else{
-                    length = start.clone().setZ(0).distanceTo(end.clone().setZ(0));
-                    leftBox.up.set(0, 0, 1);
-                }
-
-				
-				leftBox.scale.set(length, 1000000, this.width);
-				
-
-				let center = new THREE.Vector3().addVectors(start, end).multiplyScalar(0.5);
-				let diff = new THREE.Vector3().subVectors(end, start);
-				let target = new THREE.Vector3(diff.y, -diff.x, 0);
-
-				leftBox.position.set(0, 0, 0);
-				leftBox.lookAt(target);
-				leftBox.position.copy(center);
-			}
-
-			centroid.add(point);
-			min.min(point);
-			max.max(point);
-		}
-		centroid.multiplyScalar(1 / this.points.length);
-
-		for (let i = 0; i < this.boxes.length; i++) {
-			let box = this.boxes[i];
-
-			box.position.z = min.z + (max.z - min.z) / 2;
-		}
-	}
-
-	raycast (raycaster, intersects) {
-		for (let i = 0; i < this.points.length; i++) {
-			let sphere = this.spheres[i];
-
-			sphere.raycast(raycaster, intersects);
-		}
-
-		// recalculate distances because they are not necessarely correct
-		// for scaled objects.
-		// see https://github.com/mrdoob/three.js/issues/5827
-		// TODO: remove this once the bug has been fixed
-		for (let i = 0; i < intersects.length; i++) {
-			let I = intersects[i];
-			I.distance = raycaster.ray.origin.distanceTo(I.point);
-		}
-		intersects.sort(function (a, b) { return a.distance - b.distance; });
-	};
-
-	get modifiable () {
-		return this._modifiable;
-	}
-
-	set modifiable (value) {
-		this._modifiable = value;
-		this.update();
-	}
-
-}

+ 0 - 132
src/objects/tool/ProfileTool.js

@@ -1,132 +0,0 @@
-
-import * as THREE from "../../../libs/three.js/build/three.module.js";
-import {Profile} from "./Profile.js";
-import {Utils} from "../../utils.js"; 
-import {ExtendEventDispatcher} from "../../custom/ExtendEventDispatcher.js";
-
-export class ProfileTool extends ExtendEventDispatcher {
-	constructor (viewer) {
-		super();
-
-		this.viewer = viewer;
-		this.renderer = viewer.renderer;
-
-		this.addEventListener('start_inserting_profile', e => {
-			this.viewer.dispatchEvent({
-				type: 'cancel_insertions'
-			});
-		});
-
-		this.scene = new THREE.Scene();
-		this.scene.name = 'scene_profile';
-		this.light = new THREE.PointLight(0xffffff, 1.0);
-		this.scene.add(this.light);
-
-		this.viewer.inputHandler.registerInteractiveScene(this.scene);
-
-		this.onRemove = e => this.scene.remove(e.profile);
-		this.onAdd = e => this.scene.add(e.profile);
-
-		for(let profile of viewer.scene.profiles){
-			this.onAdd({profile: profile});
-		}
-
-		viewer.addEventListener("update", this.update.bind(this));
-		viewer.addEventListener("render.pass.perspective_overlay", this.render.bind(this));
-		viewer.addEventListener("scene_changed", this.onSceneChange.bind(this));
-
-		viewer.scene.addEventListener('profile_added', this.onAdd);
-		viewer.scene.addEventListener('profile_removed', this.onRemove);
-	}
-
-	onSceneChange(e){
-		if(e.oldScene){
-			e.oldScene.removeEventListeners('profile_added', this.onAdd);
-			e.oldScene.removeEventListeners('profile_removed', this.onRemove);
-		}
-
-		e.scene.addEventListener('profile_added', this.onAdd);
-		e.scene.addEventListener('profile_removed', this.onRemove);
-	}
-
-	startInsertion (args = {}) {
-		let domElement = this.viewer.renderer.domElement;
-
-		let profile = new Profile();
-		profile.name = args.name || 'Profile';
-
-		this.dispatchEvent({
-			type: 'start_inserting_profile',
-			profile: profile
-		});
-
-		this.scene.add(profile);
-
-		let cancel = {
-			callback: null
-		};
-
-		let insertionCallback = (e) => {
-			if(e.button === THREE.MOUSE.LEFT){
-				if(profile.points.length <= 1){
-					let camera = this.viewer.scene.getActiveCamera();
-					let distance = camera.position.distanceTo(profile.points[0]);
-					let clientSize = this.viewer.renderer.getSize(new THREE.Vector2());
-					let pr = Utils.projectedRadius(1, camera, distance, clientSize.width, clientSize.height);
-					let width = (10 / pr);
-
-					profile.setWidth(width);
-				}
-
-				profile.addMarker(profile.points[profile.points.length - 1].clone());
-
-				this.viewer.inputHandler.startDragging(
-					profile.spheres[profile.spheres.length - 1]);
-			} else if (e.button === THREE.MOUSE.RIGHT) {
-				cancel.callback();
-			}
-		};
-
-		cancel.callback = e => {
-			profile.removeMarker(profile.points.length - 1);
-			domElement.removeEventListener('mouseup', insertionCallback, false);
-			this.viewer.removeEventListener('cancel_insertions', cancel.callback);
-		};
-
-		this.viewer.addEventListener('cancel_insertions', cancel.callback);
-		domElement.addEventListener('mouseup', insertionCallback, false);
-
-		profile.addMarker(new THREE.Vector3(0, 0, 0));
-		this.viewer.inputHandler.startDragging(
-			profile.spheres[profile.spheres.length - 1]);
-
-		this.viewer.scene.addProfile(profile);
-
-		return profile;
-	}
-	
-	update(){
-		let camera = this.viewer.scene.getActiveCamera();
-		let profiles = this.viewer.scene.profiles;
-		let renderAreaSize = this.viewer.renderer.getSize(new THREE.Vector2());
-		let clientWidth = renderAreaSize.width;
-		let clientHeight = renderAreaSize.height;
-
-		this.light.position.copy(camera.position);
-
-		// make size independant of distance
-		for(let profile of profiles){
-			for(let sphere of profile.spheres){				
-				let distance = camera.position.distanceTo(sphere.getWorldPosition(new THREE.Vector3()));
-				let pr = Utils.projectedRadius(1, camera, distance, clientWidth, clientHeight);
-				let scale = (15 / pr);
-				sphere.scale.set(scale, scale, scale);
-			}
-		}
-	}
-
-	render(){
-		this.viewer.renderer.render(this.scene, this.viewer.scene.getActiveCamera());
-	}
-
-}

+ 0 - 239
src/objects/tool/ScreenBoxSelectTool.js

@@ -1,239 +0,0 @@
-
-import * as THREE from "../../../libs/three.js/build/three.module.js";
-import {BoxVolume} from "./Volume.js";
-import {Utils} from "../../utils.js";
-import {PointSizeType} from "../../defines.js"; 
-
-
-export class ScreenBoxSelectTool extends THREE.EventDispatcher{
-
-	constructor(viewer){
-		super();
-
-		this.viewer = viewer;
-		this.scene = new THREE.Scene();
-
-		viewer.addEventListener("update", this.update.bind(this));
-		viewer.addEventListener("render.pass.perspective_overlay", this.render.bind(this));
-		viewer.addEventListener("scene_changed", this.onSceneChange.bind(this));
-	}
-
-	onSceneChange(scene){
-		console.log("scene changed");
-	}
-
-	startInsertion(){
-		let domElement = this.viewer.renderer.domElement;
-
-		let volume = new BoxVolume();
-		volume.position.set(12345, 12345, 12345);
-		volume.showVolumeLabel = false;
-		volume.visible = false;
-		volume.update();
-		this.viewer.scene.addVolume(volume);
-
-		this.importance = 10;
-
-		let selectionBox = $(`<div style="position: absolute; border: 2px solid white; pointer-events: none; border-style:dashed"></div>`);
-		$(domElement.parentElement).append(selectionBox);
-		selectionBox.css("right", "10px");
-		selectionBox.css("bottom", "10px");
-
-		let drag = e =>{
-
-			volume.visible = true;
-
-			let mStart = e.drag.start;
-			let mEnd = e.drag.end;
-
-			let box2D = new THREE.Box2();
-			box2D.expandByPoint(mStart);
-			box2D.expandByPoint(mEnd);
-
-			selectionBox.css("left", `${box2D.min.x}px`);
-			selectionBox.css("top", `${box2D.min.y}px`);
-			selectionBox.css("width", `${box2D.max.x - box2D.min.x}px`);
-			selectionBox.css("height", `${box2D.max.y - box2D.min.y}px`);
-
-			let camera = e.viewer.scene.getActiveCamera();
-			let size = e.viewer.renderer.getSize(new THREE.Vector2());
-			let frustumSize = new THREE.Vector2(
-				camera.right - camera.left, 
-				camera.top - camera.bottom);
-
-			let screenCentroid = new THREE.Vector2().addVectors(e.drag.end, e.drag.start).multiplyScalar(0.5);
-			let pointer = new THREE.Vector3(0, 0, 0.5);
-            Utils.convertScreenPositionToNDC(pointer, screenCentroid, size.width, size.height);
-              
-            pointer.unproject(camera);
-            
-            
-            //let ray = Utils.mouseToRay( pointer, camera, size.width, size.height);
-
-			let diff = new THREE.Vector2().subVectors(e.drag.end, e.drag.start);
-			diff.divide(size).multiply(frustumSize);
-			
-            
-            volume.position.copy(pointer)
-			//volume.position.copy(ray.origin);  //orthographicCamera不能用这种方式  而且也该是用end
-			volume.up.copy(camera.up);
-			volume.rotation.copy(camera.rotation);
-			volume.scale.set(diff.x, diff.y, 1000 * 100);
-
-			e.consume();
-		};
-
-		let drop = e => {
-			this.importance = 0;
-
-			$(selectionBox).remove();
-
-			this.viewer.inputHandler.deselectAll();
-			this.viewer.inputHandler.toggleSelection(volume);
-
-			let camera = e.viewer.scene.getActiveCamera();
-			let size = e.viewer.renderer.getSize(new THREE.Vector2());
-			let screenCentroid = new THREE.Vector2().addVectors(e.drag.end, e.drag.start).multiplyScalar(0.5);
-			
-            
-             
-			let pointer = new THREE.Vector3(0, 0, 0.5);
-            Utils.convertScreenPositionToNDC(pointer, screenCentroid, size.width, size.height);
-            
-            
-            
-            let ray = Utils.mouseToRay(pointer/* screenCentroid */, camera, size.width, size.height);
-
-			//let line = new THREE.Line3(ray.origin, new THREE.Vector3().addVectors(ray.origin, ray.direction));
-
-			this.removeEventListener("drag", drag);
-			this.removeEventListener("drop", drop);
-
-			let allPointsNear = [];
-			let allPointsFar = [];
-
-			// TODO support more than one point cloud
-			for(let pointcloud of this.viewer.scene.pointclouds){
-
-				if(!pointcloud.visible){
-					continue;
-				}
-
-				let volCam = camera.clone();
-				volCam.left = -volume.scale.x / 2; 
-				volCam.right = +volume.scale.x / 2;
-				volCam.top = +volume.scale.y / 2;
-				volCam.bottom = -volume.scale.y / 2;
-				volCam.near = -volume.scale.z / 2;
-				volCam.far = +volume.scale.z / 2;
-				volCam.rotation.copy(volume.rotation);
-				volCam.position.copy(volume.position);
-
-				volCam.updateMatrix();
-				volCam.updateMatrixWorld();
-				volCam.updateProjectionMatrix();
-				volCam.matrixWorldInverse.copy(volCam.matrixWorld).invert();
-
-				let ray = new THREE.Ray(volCam.getWorldPosition(new THREE.Vector3()), volCam.getWorldDirection(new THREE.Vector3()));
-				let rayInverse = new THREE.Ray(
-					ray.origin.clone().add(ray.direction.clone().multiplyScalar(volume.scale.z)),
-					ray.direction.clone().multiplyScalar(-1));
-                    
-                    
-                    
-                let diff = new THREE.Vector2().subVectors(e.drag.end, e.drag.start);
-				let pickerSettings = {
-					width:  16, //renderTarget大小,数值越大识别精度越高 原本的8太低了
-					height:  16, 
-					pickWindowSize: 16, //??????
-                     
-					all: true,
-					pickClipped: true,
-					pointSizeType: PointSizeType.FIXED,
-					pointSize: 1
-                }; 
-                
-                 
-				let pointsNear = pointcloud.pick(viewer, null, volCam, ray, pickerSettings);
-
-				volCam.rotateX(Math.PI);
-				volCam.updateMatrix();
-				volCam.updateMatrixWorld();
-				volCam.updateProjectionMatrix();
-				volCam.matrixWorldInverse.copy(volCam.matrixWorld).invert();
-				let pointsFar = pointcloud.pick(viewer,null, volCam, rayInverse, pickerSettings);
-
-				pointsNear && allPointsNear.push(...pointsNear);
-				pointsFar && allPointsFar.push(...pointsFar);
-			}
-
-			/* if(allPointsNear.length > 0 && allPointsFar.length > 0){
-				let viewLine = new THREE.Line3(ray.origin, new THREE.Vector3().addVectors(ray.origin, ray.direction));
-
-				let closestOnLine = allPointsNear.map(p => viewLine.closestPointToPoint(p.position, false, new THREE.Vector3()));
-				let closest = closestOnLine.sort( (a, b) => ray.origin.distanceTo(a) - ray.origin.distanceTo(b))[0];
-
-				let farthestOnLine = allPointsFar.map(p => viewLine.closestPointToPoint(p.position, false, new THREE.Vector3()));
-				let farthest = farthestOnLine.sort( (a, b) => ray.origin.distanceTo(b) - ray.origin.distanceTo(a))[0];
-
-				let distance = closest.distanceTo(farthest);
-				let centroid = new THREE.Vector3().addVectors(closest, farthest).multiplyScalar(0.5);
-				volume.scale.z = distance * 1.1;
-				volume.position.copy(centroid);
-			} */
-            if(allPointsNear.length > 0 || allPointsFar.length > 0){
-				let viewLine = new THREE.Line3(ray.origin, new THREE.Vector3().addVectors(ray.origin, ray.direction));
-
-				let closestOnLine = allPointsNear.map(p => viewLine.closestPointToPoint(p.position, false, new THREE.Vector3()));
-				let closests = closestOnLine.sort( (a, b) => ray.origin.distanceTo(a) - ray.origin.distanceTo(b))//[0];
-
-				let farthestOnLine = allPointsFar.map(p => viewLine.closestPointToPoint(p.position, false, new THREE.Vector3()));
-				let farthests = farthestOnLine.sort( (a, b) => ray.origin.distanceTo(b) - ray.origin.distanceTo(a))//[0];
-
-
-                let closest, farthest;
-                if(closests.length == 0){
-                    closest = farthests[farthests.length-1];
-                    farthest = farthests[0]
-                }else if(farthests.length == 0){
-                    closest = closests[closests.length-1];
-                    farthest = closests[0]
-                }else{
-                    closest = closests[0]
-                    farthest = farthests[0]
-                }
-
-
-
-				let distance = closest.distanceTo(farthest);
-				let centroid = new THREE.Vector3().addVectors(closest, farthest).multiplyScalar(0.5);
-				volume.scale.z = distance * 1.1;
-				//volume.position.copy(centroid);
-                
-                var pos2d = centroid.project(camera);   //改变深度
-                pointer.setZ(pos2d.z)
-                pointer.unproject(camera)    
-                volume.position.copy(pointer);
-                
-                
-			}
-			volume.clip = true;
-		};
-
-		this.addEventListener("drag", drag);
-		this.addEventListener("drop", drop);
-
-		viewer.inputHandler.addInputListener(this);
-
-		return volume;
-	}
-
-	update(e){
-		//console.log(e.delta)
-	}
-
-	render(){
-		this.viewer.renderer.render(this.scene, this.viewer.scene.getActiveCamera());
-	}
-
-}

+ 0 - 78
src/objects/tool/SpotLightHelper.js

@@ -1,78 +0,0 @@
-
-import * as THREE from "../../../libs/three.js/build/three.module.js";
-
-export class SpotLightHelper extends THREE.Object3D{
-
-	constructor(light, color){
-		super();
-
-		this.light = light;
-		this.color = color;
-
-		//this.up.set(0, 0, 1);
-		this.updateMatrix();
-		this.updateMatrixWorld();
-
-		{ // SPHERE
-			let sg = new THREE.SphereGeometry(1, 32, 32);
-			let sm = new THREE.MeshNormalMaterial();
-			this.sphere = new THREE.Mesh(sg, sm);
-			this.sphere.scale.set(0.5, 0.5, 0.5);
-			this.add(this.sphere);
-		}
-
-		{ // LINES
-			
-
-			let positions = new Float32Array([
-				+0, +0, +0,     +0, +0, -1,
-
-				+0, +0, +0,     -1, -1, -1,
-				+0, +0, +0,     +1, -1, -1,
-				+0, +0, +0,     +1, +1, -1,
-				+0, +0, +0,     -1, +1, -1,
-
-				-1, -1, -1,     +1, -1, -1,
-				+1, -1, -1,     +1, +1, -1,
-				+1, +1, -1,     -1, +1, -1,
-				-1, +1, -1,     -1, -1, -1,
-			]);
-
-			let geometry = new THREE.BufferGeometry();
-			geometry.setAttribute("position", new THREE.BufferAttribute(positions, 3));
-
-			let material = new THREE.LineBasicMaterial();
-
-			this.frustum = new THREE.LineSegments(geometry, material);
-			this.add(this.frustum);
-
-		}
-
-		this.update();
-	}
-
-	update(){
-
-		this.light.updateMatrix();
-		this.light.updateMatrixWorld();
-
-		let position = this.light.position;
-		let target = new THREE.Vector3().addVectors(
-			this.light.position, this.light.getWorldDirection(new THREE.Vector3()).multiplyScalar(-1));
-		
-		let quat = new THREE.Quaternion().setFromRotationMatrix(
-			new THREE.Matrix4().lookAt( position, target, new THREE.Vector3( 0, 0, 1 ) )
-		);
-
-		this.setRotationFromQuaternion(quat);
-		this.position.copy(position);
-
-
-		let coneLength = (this.light.distance > 0) ? this.light.distance : 1000;
-		let coneWidth = coneLength * Math.tan( this.light.angle * 0.5 );
-
-		this.frustum.scale.set(coneWidth, coneWidth, coneLength);
-
-	}
-
-}

+ 0 - 95
src/objects/tool/TagTool.js

@@ -1,95 +0,0 @@
-
-import * as THREE from "../../../libs/three.js/build/three.module.js";
-
-import math from "../../utils/math.js";
-import {Utils} from "../../utils.js"; 
-
-import Tag from '../Tag.js'
-import {ExtendEventDispatcher} from "../../custom/ExtendEventDispatcher.js";
-
-export class TagTool extends ExtendEventDispatcher{
-	constructor (viewer) {
-		super();
-        
-        
-        
-        
-        this.viewer = viewer
-        
-        
-        
-        this.viewer.addEventListener('start_inserting_tag', e => {
-			this.viewer.dispatchEvent({
-				type: 'cancel_insertions'
-			});
-		});
-    }
-    
-    
-    
-    
-    createTagFromData(data){
-        let tag = new Tag({
-            title: data.title, position: data.position,  normal: data.normal,
-            root: data.root   //e.intersect.pointcloud || e.intersect.object
-        })
-        
-        return tag
-        
-    }
-     
-    
-    startInsertion (args = {}, callback, cancelFun) {
-        let deferred = $.Deferred();
-         
-        this.viewer.dispatchEvent({
-			type: 'start_inserting_tag' 
-			 
-		});
-        this.adding = true
-        
-        let cancel = ()=>{
-            end()
-        }
-        let end = ()=>{
-            this.adding = false
-            viewer.dispatchEvent({type:"endTagMove"})
-            this.viewer.removeEventListener('global_click', click)
-        }
-        let click = (e)=>{
-            
-            
-            var worldPos = e.intersect && (/* e.intersect.orthoIntersect ||  */e.intersect.location)
-            if(!worldPos){
-                return  
-            }
-            
-            let localPos = Potree.Utils.datasetPosTransform({ toDataset: true, pointcloud:e.intersect.pointcloud, object:e.intersect.object,  position:worldPos })
-
-            
-            let tag = new Tag({
-                title: '1', position: localPos,  normal:e.intersect.normal,
-                root: e.intersect.pointcloud || e.intersect.object
-            }) 
-            
-            //pointcloud里加一个normal 的非float32
-            
-            
-            
-            end()
-            e.consume && e.consume()
-            deferred.resolve(tag)
-            
-            
-            return {stopContinue:true}
-            
-        }
-        this.viewer.addEventListener('global_click', click, 10)
-        return deferred.promise()
-    }  
-    
-    
-    
-    
-}
-

File diff suppressed because it is too large
+ 0 - 1981
src/objects/tool/TransformControls.js


+ 0 - 910
src/objects/tool/TransformationTool.js

@@ -1,910 +0,0 @@
-
-import * as THREE from "../../../libs/three.js/build/three.module.js";
-import {Utils} from "../../utils.js";
-
-
-
-//add-------------------------------------
-const OpaWhenNotSelect = 0.75
-const ScaleRatio = 4
-const OutlineColor = 0x666666
-//----------------------------------------
-const hideFocusHandles = true//add
-
-
-export class TransformationTool {
-	constructor(viewer) {
-		this.viewer = viewer;
-
-		this.scene = new THREE.Scene();
-
-		this.selection = [];
-		this.pivot = new THREE.Vector3();
-		this.dragging = false;
-		this.showPickVolumes = false;
-
-		this.viewer.inputHandler.registerInteractiveScene(this.scene);
-		this.viewer.inputHandler.addEventListener('selection_changed', (e) => {
-			for(let selected of this.selection){
-				this.viewer.inputHandler.blacklist.delete(selected);
-			}
-
-			this.selection = e.selection;
-
-			for(let selected of this.selection){
-				this.viewer.inputHandler.blacklist.add(selected);
-			}
-
-		});
-
-
-        this.viewer.addEventListener('global_touchstart',(e)=>{ //add
-            this.update()
-        })
-
-
-
-		let red = Potree.config.axis.x.color
-		let green = Potree.config.axis.y.color
-		let blue = Potree.config.axis.z.color
-		
-		this.activeHandle = null;
-		this.scaleHandles = {
-			"scale.x+": {name: "scale.x+", node: new THREE.Object3D(), color: red, alignment: [+1, +0, +0]},
-			"scale.x-": {name: "scale.x-", node: new THREE.Object3D(), color: red, alignment: [-1, +0, +0]},
-			"scale.y+": {name: "scale.y+", node: new THREE.Object3D(), color: green, alignment: [+0, +1, +0]},
-			"scale.y-": {name: "scale.y-", node: new THREE.Object3D(), color: green, alignment: [+0, -1, +0]},
-			"scale.z+": {name: "scale.z+", node: new THREE.Object3D(), color: blue, alignment: [+0, +0, +1]},
-			"scale.z-": {name: "scale.z-", node: new THREE.Object3D(), color: blue, alignment: [+0, +0, -1]},
-		};
-		this.focusHandles = {
-			"focus.x+": {name: "focus.x+", node:  new THREE.Object3D(), color: red, alignment: [+1, +0, +0]},
-			"focus.x-": {name: "focus.x-", node:  new THREE.Object3D(), color: red, alignment: [-1, +0, +0]},
-			"focus.y+": {name: "focus.y+", node:  new THREE.Object3D(), color: green, alignment: [+0, +1, +0]},
-			"focus.y-": {name: "focus.y-", node:  new THREE.Object3D(), color: green, alignment: [+0, -1, +0]},
-			"focus.z+": {name: "focus.z+", node:  new THREE.Object3D(), color: blue, alignment: [+0, +0, +1]},
-			"focus.z-": {name: "focus.z-", node:  new THREE.Object3D(), color: blue, alignment: [+0, +0, -1]},
-		};
-		this.translationHandles = {
-			"translation.x": {name: "translation.x", node:  new THREE.Object3D(), color: red, alignment: [1, 0, 0]},
-			"translation.y": {name: "translation.y", node:  new THREE.Object3D(), color: green, alignment: [0, 1, 0]},
-			"translation.z": {name: "translation.z", node:  new THREE.Object3D(), color: blue, alignment: [0, 0, 1]},
-		};
-		this.rotationHandles = {
-			"rotation.x": {name: "rotation.x", node:  new THREE.Object3D(), color: red, alignment: [1, 0, 0]},
-			"rotation.y": {name: "rotation.y", node:  new THREE.Object3D(), color: green, alignment: [0, 1, 0]},
-			"rotation.z": {name: "rotation.z", node:  new THREE.Object3D(), color: blue, alignment: [0, 0, 1]},
-		};
-		this.handles = Object.assign({}, this.scaleHandles,    hideFocusHandles?{}:this.focusHandles, this.translationHandles, this.rotationHandles);
-		this.pickVolumes = [];
-
-		this.initializeScaleHandles();
-		this.initializeFocusHandles();
-		this.initializeTranslationHandles();
-		this.initializeRotationHandles();
-
-
-		let boxFrameGeometry = new THREE.Geometry();
-		{
-			// bottom
-			boxFrameGeometry.vertices.push(new THREE.Vector3(-0.5, -0.5, 0.5));
-			boxFrameGeometry.vertices.push(new THREE.Vector3(0.5, -0.5, 0.5));
-			boxFrameGeometry.vertices.push(new THREE.Vector3(0.5, -0.5, 0.5));
-			boxFrameGeometry.vertices.push(new THREE.Vector3(0.5, -0.5, -0.5));
-			boxFrameGeometry.vertices.push(new THREE.Vector3(0.5, -0.5, -0.5));
-			boxFrameGeometry.vertices.push(new THREE.Vector3(-0.5, -0.5, -0.5));
-			boxFrameGeometry.vertices.push(new THREE.Vector3(-0.5, -0.5, -0.5));
-			boxFrameGeometry.vertices.push(new THREE.Vector3(-0.5, -0.5, 0.5));
-			// top
-			boxFrameGeometry.vertices.push(new THREE.Vector3(-0.5, 0.5, 0.5));
-			boxFrameGeometry.vertices.push(new THREE.Vector3(0.5, 0.5, 0.5));
-			boxFrameGeometry.vertices.push(new THREE.Vector3(0.5, 0.5, 0.5));
-			boxFrameGeometry.vertices.push(new THREE.Vector3(0.5, 0.5, -0.5));
-			boxFrameGeometry.vertices.push(new THREE.Vector3(0.5, 0.5, -0.5));
-			boxFrameGeometry.vertices.push(new THREE.Vector3(-0.5, 0.5, -0.5));
-			boxFrameGeometry.vertices.push(new THREE.Vector3(-0.5, 0.5, -0.5));
-			boxFrameGeometry.vertices.push(new THREE.Vector3(-0.5, 0.5, 0.5));
-			// sides
-			boxFrameGeometry.vertices.push(new THREE.Vector3(-0.5, -0.5, 0.5));
-			boxFrameGeometry.vertices.push(new THREE.Vector3(-0.5, 0.5, 0.5));
-			boxFrameGeometry.vertices.push(new THREE.Vector3(0.5, -0.5, 0.5));
-			boxFrameGeometry.vertices.push(new THREE.Vector3(0.5, 0.5, 0.5));
-			boxFrameGeometry.vertices.push(new THREE.Vector3(0.5, -0.5, -0.5));
-			boxFrameGeometry.vertices.push(new THREE.Vector3(0.5, 0.5, -0.5));
-			boxFrameGeometry.vertices.push(new THREE.Vector3(-0.5, -0.5, -0.5));
-			boxFrameGeometry.vertices.push(new THREE.Vector3(-0.5, 0.5, -0.5));
-		}
-		this.frame = new THREE.LineSegments(boxFrameGeometry, new THREE.LineBasicMaterial({color: 0xffff00}));
-		this.scene.add(this.frame);
-        viewer.setObjectLayers(this.scene, 'transformationTool' )
-		
-	}
-
-	initializeScaleHandles(){
-		let sgSphere = new THREE.SphereGeometry(1, 32, 32);
-		let sgLowPolySphere = new THREE.SphereGeometry(1, 16, 16);
-
-		for(let handleName of Object.keys(this.scaleHandles)){
-			let handle = this.scaleHandles[handleName];
-			let node = handle.node;
-			this.scene.add(node);
-			node.position.set(...handle.alignment).multiplyScalar(0.5);
-
-			let material = new THREE.MeshBasicMaterial({
-				color: handle.color,
-				opacity: OpaWhenNotSelect,
-				transparent: true
-				});
-
-			let outlineMaterial = new THREE.MeshBasicMaterial({
-				color: OutlineColor, 
-				side: THREE.BackSide,
-				opacity: OpaWhenNotSelect,
-				transparent: true});
-
-			let pickMaterial = new THREE.MeshNormalMaterial({
-				opacity: 0.2,
-				transparent: true,
-				visible: this.showPickVolumes});
-
-			let sphere = new THREE.Mesh(sgSphere, material);
-			sphere.scale.set(2, 2, 2 );
-			sphere.name = `${handleName}.handle`;
-			node.add(sphere);
-			
-			let outline = new THREE.Mesh(sgSphere, outlineMaterial);
-			outline.scale.set(1.1, 1.1, 1.1);
-			outline.name = `${handleName}.outline`;
-			sphere.add(outline);
-
-			let pickSphere = new THREE.Mesh(sgLowPolySphere, pickMaterial);
-			pickSphere.name = `${handleName}.pick_volume`;
-			pickSphere.scale.set(2, 2, 2);
-			sphere.add(pickSphere);
-			pickSphere.handle = handleName;
-			this.pickVolumes.push(pickSphere);
-
-			node.setOpacity = (target) => {
-				let opacity = {x: material.opacity};
-				let t = new TWEEN.Tween(opacity).to({x: target}, 100);
-				t.onUpdate(() => {
-					sphere.visible = opacity.x > 0;
-					pickSphere.visible = opacity.x > 0;
-					material.opacity = opacity.x;
-					outlineMaterial.opacity = opacity.x;
-					pickSphere.material.opacity = opacity.x * 0.5;
-				});
-				t.start();
-			};
-
-			pickSphere.addEventListener("drag", (e) => this.dragScaleHandle(e));
-			pickSphere.addEventListener("drop", (e) => this.dropScaleHandle(e));
-
-			pickSphere.addEventListener("mouseover", e => {
-				//node.setOpacity(1);
-			});
-
-			pickSphere.addEventListener("click", e => {
-				e.consume();
-			});
-
-			pickSphere.addEventListener("mouseleave", e => {
-				//node.setOpacity(OpaWhenNotSelect);
-			});
-		}
-	}
-
-	initializeFocusHandles(){
-        if(hideFocusHandles)return//add
-		//let sgBox = new THREE.BoxGeometry(1, 1, 1);
-		let sgPlane = new THREE.PlaneGeometry(4, 4, 1, 1);
-		let sgLowPolySphere = new THREE.SphereGeometry(1, 16, 16);
-
-		let texture = new THREE.TextureLoader().load(`${exports.resourcePath}/icons/eye_2.png`);
-
-		for(let handleName of Object.keys(this.focusHandles)){
-			let handle = this.focusHandles[handleName];
-			let node = handle.node;
-			this.scene.add(node);
-			let align = handle.alignment;
-
-			//node.lookAt(new THREE.Vector3().addVectors(node.position, new THREE.Vector3(...align)));
-			node.lookAt(new THREE.Vector3(...align));
-
-			let off = 0.8;
-			if(align[0] === 1){
-				node.position.set(1, off, -off).multiplyScalar(0.5);
-				node.rotation.z = Math.PI / 2;
-			}else if(align[0] === -1){
-				node.position.set(-1, -off, -off).multiplyScalar(0.5);
-				node.rotation.z = Math.PI / 2;
-			}else if(align[1] === 1){
-				node.position.set(-off, 1, -off).multiplyScalar(0.5);
-				node.rotation.set(Math.PI / 2, Math.PI, 0.0);
-			}else if(align[1] === -1){
-				node.position.set(off, -1, -off).multiplyScalar(0.5);
-				node.rotation.set(Math.PI / 2, 0.0, 0.0);
-			}else if(align[2] === 1){
-				node.position.set(off, off, 1).multiplyScalar(0.5);
-			}else if(align[2] === -1){
-				node.position.set(-off, off, -1).multiplyScalar(0.5);
-			}
-
-			let material = new THREE.MeshBasicMaterial({
-				color: handle.color,
-				opacity: 0,
-				transparent: true,
-				map: texture
-			});
-
-			//let outlineMaterial = new THREE.MeshBasicMaterial({
-			//	color: 0x000000, 
-			//	side: THREE.BackSide,
-			//	opacity: 0,
-			//	transparent: true});
-
-			let pickMaterial = new THREE.MeshNormalMaterial({
-				//opacity: 0,
-				transparent: true,
-				visible: this.showPickVolumes});
-
-			let box = new THREE.Mesh(sgPlane, material);
-			box.name = `${handleName}.handle`;
-			box.scale.set(1.5, 1.5, 1.5);
-			box.position.set(0, 0, 0);
-			box.visible = false;
-			node.add(box);
-			//handle.focusNode = box;
-			
-			//let outline = new THREE.Mesh(sgPlane, outlineMaterial);
-			//outline.scale.set(1.4, 1.4, 1.4);
-			//outline.name = `${handleName}.outline`;
-			//box.add(outline);
-
-			let pickSphere = new THREE.Mesh(sgLowPolySphere, pickMaterial);
-			pickSphere.name = `${handleName}.pick_volume`;
-			pickSphere.scale.set(2, 2, 2);
-			box.add(pickSphere);
-			pickSphere.handle = handleName;
-			this.pickVolumes.push(pickSphere);
-
-			node.setOpacity = (target) => {
-				let opacity = {x: material.opacity};
-				let t = new TWEEN.Tween(opacity).to({x: target}, 100);
-				t.onUpdate(() => {
-					pickSphere.visible = opacity.x > 0;
-					box.visible = opacity.x > 0;
-					material.opacity = opacity.x;
-					//outlineMaterial.opacity = opacity.x;
-					pickSphere.material.opacity = opacity.x * 0.5;
-				});
-				t.start();
-			};
-
-			//pickSphere.addEventListener("drag", e => {});
-
-			pickSphere.addEventListener("mouseup", e => {
-				e.consume();
-			});
-
-			pickSphere.addEventListener("mousedown", e => {
-				e.consume();
-			});
-
-			pickSphere.addEventListener("click", e => {
-				e.consume();
-
-				let selected = this.selection[0];
-				let maxScale = Math.max(...selected.scale.toArray());
-				let minScale = Math.min(...selected.scale.toArray());
-				let handleLength = Math.abs(selected.scale.dot(new THREE.Vector3(...handle.alignment)));
-				let alignment = new THREE.Vector3(...handle.alignment).multiplyScalar(2 * maxScale / handleLength);
-				alignment.applyMatrix4(selected.matrixWorld);
-				let newCamPos = alignment;
-				let newCamTarget = selected.getWorldPosition(new THREE.Vector3());
-
-				Utils.moveTo(this.viewer.scene, newCamPos, newCamTarget);
-			});
-
-			pickSphere.addEventListener("mouseover", e => {
-				//box.setOpacity(1);
-			});
-
-			pickSphere.addEventListener("mouseleave", e => {
-				//box.setOpacity(OpaWhenNotSelect);
-			});
-		}
-	}
-
-	initializeTranslationHandles(){
-
-		let boxGeometry = new THREE.BoxGeometry(1, 1, 1);
-
-		for(let handleName of Object.keys(this.translationHandles)){
-			let handle = this.handles[handleName];
-			let node = handle.node;
-			this.scene.add(node);
-
-			let material = new THREE.MeshBasicMaterial({
-				color: handle.color,
-				opacity: OpaWhenNotSelect,
-				transparent: true});
-
-			let outlineMaterial = new THREE.MeshBasicMaterial({
-				color: OutlineColor, 
-				side: THREE.BackSide,
-				opacity: OpaWhenNotSelect,
-				transparent: true});
-
-			let pickMaterial = new THREE.MeshNormalMaterial({
-				opacity: 0.2,
-				transparent: true,
-				visible: this.showPickVolumes
-			});
-
-			let box = new THREE.Mesh(boxGeometry, material);
-			box.name = `${handleName}.handle`;
-			box.scale.set(1, 1, 36);
-			box.lookAt(new THREE.Vector3(...handle.alignment));
-			box.renderOrder = 10;
-			node.add(box);
-			handle.translateNode = box;
-
-			let outline = new THREE.Mesh(boxGeometry, outlineMaterial);
-			outline.name = `${handleName}.outline`;
-			outline.scale.set(1.3, 1.3, 1.01);
-			outline.renderOrder = 0;
-			box.add(outline);
-
-			let pickVolume = new THREE.Mesh(boxGeometry, pickMaterial);
-			pickVolume.name = `${handleName}.pick_volume`;
-			pickVolume.scale.set(4, 4, 1.1);
-			pickVolume.handle = handleName;
-			box.add(pickVolume);
-			this.pickVolumes.push(pickVolume);
-
-			node.setOpacity = (target) => {
-				let opacity = {x: material.opacity};
-				let t = new TWEEN.Tween(opacity).to({x: target}, 100);
-				t.onUpdate(() => {
-					box.visible = opacity.x > 0;
-					pickVolume.visible = opacity.x > 0;
-					material.opacity = opacity.x;
-					outlineMaterial.opacity = opacity.x;
-					pickMaterial.opacity = opacity.x * 0.5;
-				});
-				t.start();
-			};
-
-			pickVolume.addEventListener("drag", (e) => {this.dragTranslationHandle(e)});
-			pickVolume.addEventListener("drop", (e) => {this.dropTranslationHandle(e)});
-		}
-	}
-
-	initializeRotationHandles(){
-		let adjust = 1.5;
-		let torusGeometry = new THREE.TorusGeometry(1, adjust * 0.015, 8, 64, Math.PI / 2);
-		let outlineGeometry = new THREE.TorusGeometry(1, adjust * 0.018, 8, 64, Math.PI / 2);
-		let pickGeometry = new THREE.TorusGeometry(1, adjust * 0.04, 6, 4, Math.PI / 2);
-
-		for(let handleName of Object.keys(this.rotationHandles)){
-			let handle = this.handles[handleName];
-			let node = handle.node;
-			this.scene.add(node);
-
-			let material = new THREE.MeshBasicMaterial({
-				color: handle.color,
-				opacity: OpaWhenNotSelect,
-				transparent: true
-            });
-
-			let outlineMaterial = new THREE.MeshBasicMaterial({
-				color: OutlineColor, 
-				side: THREE.BackSide,
-				opacity: OpaWhenNotSelect,
-				transparent: true
-            });
-
-			let pickMaterial = new THREE.MeshNormalMaterial({
-				opacity: 0.2,
-				transparent: true,
-				visible: this.showPickVolumes
-			});
-
-			let box = new THREE.Mesh(torusGeometry, material);
-			box.name = `${handleName}.handle`;
-			box.scale.set(30, 30, 30);
-			box.lookAt(new THREE.Vector3(...handle.alignment));
-			node.add(box);
-			handle.translateNode = box;
-
-			let outline = new THREE.Mesh(outlineGeometry, outlineMaterial);
-			outline.name = `${handleName}.outline`;
-			outline.scale.set(1, 1, 1);
-			outline.renderOrder = 0;
-			box.add(outline);
-
-			let pickVolume = new THREE.Mesh(pickGeometry, pickMaterial);
-			pickVolume.name = `${handleName}.pick_volume`;
-			pickVolume.scale.set(1, 1, 1);
-			pickVolume.handle = handleName;
-			box.add(pickVolume);
-			this.pickVolumes.push(pickVolume);
-
-			node.setOpacity = (target) => {
-				let opacity = {x: material.opacity};
-				let t = new TWEEN.Tween(opacity).to({x: target}, 100);
-				t.onUpdate(() => {
-					box.visible = opacity.x > 0;
-					pickVolume.visible = opacity.x > 0;
-					material.opacity = opacity.x;
-					outlineMaterial.opacity = opacity.x;
-					pickMaterial.opacity = opacity.x * 0.5;
-				});
-				t.start();
-			};
-
-
-			//pickVolume.addEventListener("mouseover", (e) => {
-			//	//let a = this.viewer.scene.getActiveCamera().getWorldDirection(new THREE.Vector3()).dot(pickVolume.getWorldDirection(new THREE.Vector3()));
-			//	console.log(pickVolume.getWorldDirection(new THREE.Vector3()));
-			//});
-			
-			pickVolume.addEventListener("drag", (e) => {this.dragRotationHandle(e)});
-			pickVolume.addEventListener("drop", (e) => {this.dropRotationHandle(e)});
-		}
-	}
-
-	dragRotationHandle(e){
-		let drag = e.drag;
-		let handle = this.activeHandle;
-		let camera = this.viewer.scene.getActiveCamera();
-
-		if(!handle){
-			return
-		};
-
-		let localNormal = new THREE.Vector3(...handle.alignment);
-		let n = new THREE.Vector3();
-		n.copy(new THREE.Vector4(...localNormal.toArray(), 0).applyMatrix4(handle.node.matrixWorld));
-		n.normalize();
-
-		if (!drag.intersectionStart){
-
-			//this.viewer.scene.scene.remove(this.debug);
-			//this.debug = new THREE.Object3D();
-			//this.viewer.scene.scene.add(this.debug);
-			//Utils.debugSphere(this.debug, drag.location, 3, 0xaaaaaa);
-			//let debugEnd = drag.location.clone().add(n.clone().multiplyScalar(20));
-			//Utils.debugLine(this.debug, drag.location, debugEnd, 0xff0000);
-
-			drag.intersectionStart = drag.location;
-			drag.objectStart = drag.object.getWorldPosition(new THREE.Vector3());
-			drag.handle = handle;
-
-			let plane = new THREE.Plane().setFromNormalAndCoplanarPoint(n, drag.intersectionStart);
-
-			drag.dragPlane = plane;
-			drag.pivot = drag.intersectionStart;
-		}else{
-			handle = drag.handle;
-		}
-
-		this.dragging = true;
-
-		let pointer = this.viewer.inputHandler.pointer
-		let domElement = this.viewer.renderer.domElement;
-		let ray = Utils.mouseToRay(pointer, camera, domElement.clientWidth, domElement.clientHeight);
-		
-		let I = ray.intersectPlane(drag.dragPlane, new THREE.Vector3());
-
-		if (I) {
-			let center = this.scene.getWorldPosition(new THREE.Vector3());
-			let from = drag.pivot;
-			let to = I;
-
-			let v1 = from.clone().sub(center).normalize();
-			let v2 = to.clone().sub(center).normalize();
-
-			let angle = Math.acos(v1.dot(v2));
-			let sign = Math.sign(v1.cross(v2).dot(n));
-			angle = angle * sign;
-			if (Number.isNaN(angle)) {
-				return;
-			}
-
-			let normal = new THREE.Vector3(...handle.alignment);
-			for (let selection of this.selection) {
-				selection.rotateOnAxis(normal, angle);
-				selection.dispatchEvent({
-					type: "orientation_changed",
-					object: selection
-				});
-			}
-
-			drag.pivot = I;
-		}
-	}
-
-	dropRotationHandle(e){
-		this.dragging = false;
-		this.setActiveHandle(null);
-	}
-
-	dragTranslationHandle(e){
-		let drag = e.drag;
-		let handle = this.activeHandle;
-		let camera = this.viewer.scene.getActiveCamera();
-			
-		if(!drag.intersectionStart && handle){
-			drag.intersectionStart = drag.location;
-			drag.objectStart = drag.object.getWorldPosition(new THREE.Vector3());
-
-			let start = drag.intersectionStart;
-			let dir = new THREE.Vector4(...handle.alignment, 0).applyMatrix4(this.scene.matrixWorld);
-			let end = new THREE.Vector3().addVectors(start, dir);
-			let line = new THREE.Line3(start.clone(), end.clone());
-			drag.line = line;
-
-			let camOnLine = line.closestPointToPoint(camera.position, false, new THREE.Vector3());
-			let normal = new THREE.Vector3().subVectors(camera.position, camOnLine);
-			let plane = new THREE.Plane().setFromNormalAndCoplanarPoint(normal, drag.intersectionStart);
-			drag.dragPlane = plane;
-			drag.pivot = drag.intersectionStart;
-		}else{
-			handle = drag.handle;
-		}
-
-		this.dragging = true;
-
-		{
-			let pointer = this.viewer.inputHandler.pointer
-			let domElement = this.viewer.renderer.domElement;
-			let ray = Utils.mouseToRay(pointer, camera, domElement.clientWidth, domElement.clientHeight);
-			let I = ray.intersectPlane(drag.dragPlane, new THREE.Vector3());
-
-			if (I) {
-				let iOnLine = drag.line.closestPointToPoint(I, false, new THREE.Vector3());
-
-				let diff = new THREE.Vector3().subVectors(iOnLine, drag.pivot);
-
-				for (let selection of this.selection) {
-					selection.position.add(diff);
-					selection.dispatchEvent({
-						type: "position_changed",
-						object: selection
-					});
-				}
-
-				drag.pivot = drag.pivot.add(diff);
-			}
-		}
-	}
-
-	dropTranslationHandle(e){
-		this.dragging = false;
-		this.setActiveHandle(null);
-	}
-
-	dropScaleHandle(e){
-		this.dragging = false;
-		this.setActiveHandle(null);
-	}
-
-	dragScaleHandle(e){
-		let drag = e.drag;
-		let handle = this.activeHandle;
-		let camera = this.viewer.scene.getActiveCamera();
-
-		if(!drag.intersectionStart){
-			drag.intersectionStart = drag.location;
-			drag.objectStart = drag.object.getWorldPosition(new THREE.Vector3());
-			drag.handle = handle;
-
-			let start = drag.intersectionStart;
-			let dir = new THREE.Vector4(...handle.alignment, 0).applyMatrix4(this.scene.matrixWorld);
-			let end = new THREE.Vector3().addVectors(start, dir);
-			let line = new THREE.Line3(start.clone(), end.clone());
-			drag.line = line;
-
-			let camOnLine = line.closestPointToPoint(camera.position, false, new THREE.Vector3());
-			let normal = new THREE.Vector3().subVectors(camera.position, camOnLine);
-			let plane = new THREE.Plane().setFromNormalAndCoplanarPoint(normal, drag.intersectionStart);
-			drag.dragPlane = plane;
-			drag.pivot = drag.intersectionStart;
-
-			//Utils.debugSphere(viewer.scene.scene, drag.pivot, 0.05);
-		}else{
-			handle = drag.handle;
-		}
-
-		this.dragging = true;
-
-		{
-			let pointer = this.viewer.inputHandler.pointer
-			let domElement = this.viewer.renderer.domElement;
-			let ray = Utils.mouseToRay(pointer, camera, domElement.clientWidth, domElement.clientHeight);
-			let I = ray.intersectPlane(drag.dragPlane, new THREE.Vector3());
-
-			if (I) {
-				let iOnLine = drag.line.closestPointToPoint(I, false, new THREE.Vector3());
-				let direction = handle.alignment.reduce( (a, v) => a + v, 0);
-
-				let toObjectSpace = this.selection[0].matrixWorld.clone().invert();
-				let iOnLineOS = iOnLine.clone().applyMatrix4(toObjectSpace);
-				let pivotOS = drag.pivot.clone().applyMatrix4(toObjectSpace);
-				let diffOS = new THREE.Vector3().subVectors(iOnLineOS, pivotOS);
-				let dragDirectionOS = diffOS.clone().normalize();
-				if(iOnLine.distanceTo(drag.pivot) === 0){
-					dragDirectionOS.set(0, 0, 0);
-				}
-				let dragDirection = dragDirectionOS.dot(new THREE.Vector3(...handle.alignment));
-
-				let diff = new THREE.Vector3().subVectors(iOnLine, drag.pivot);
-				let diffScale = new THREE.Vector3(...handle.alignment).multiplyScalar(diff.length() * direction * dragDirection);
-				let diffPosition = diff.clone().multiplyScalar(0.5);
-   
- 
- 
-				for (let selection of this.selection) {
-                    //xzw 改:否则不跟手
-                    let diffScale_ = diffScale.clone().divide(selection.boundingBox.getSize(new THREE.Vector3))
-					selection.scale.add(diffScale_);
-                    //selection.scale.add(diffScale);
-					selection.scale.x = Math.max(0.1, selection.scale.x);
-					selection.scale.y = Math.max(0.1, selection.scale.y);
-					selection.scale.z = Math.max(0.1, selection.scale.z);
-					selection.position.add(diffPosition);
-                    
-                    
-					selection.dispatchEvent({
-						type: "position_changed",
-						object: selection
-					});
-					selection.dispatchEvent({
-						type: "scale_changed",
-						object: selection
-					});
-				}
-
-				drag.pivot.copy(iOnLine);
-				//Utils.debugSphere(viewer.scene.scene, drag.pivot, 0.05);
-			}
-		}
-	}
-
-	setActiveHandle(handle){
-		if(this.dragging){
-			return;
-		}
-
-		if(this.activeHandle === handle){
-			return;
-		}
-
-		this.activeHandle = handle;
-
-		if(handle === null){
-			for(let handleName of Object.keys(this.handles)){
-				let handle = this.handles[handleName];
-				handle.node.setOpacity(0);
-			}
-		}
-
-		if(!hideFocusHandles){
-            for(let handleName of Object.keys(this.focusHandles)){
-                let handle = this.focusHandles[handleName];
-
-                if(this.activeHandle === handle){
-                    handle.node.setOpacity(1.0);
-                }else{
-                    handle.node.setOpacity(OpaWhenNotSelect)
-                }
-            }
-		}
-
-		for(let handleName of Object.keys(this.translationHandles)){
-			let handle = this.translationHandles[handleName];
-
-			if(this.activeHandle === handle){
-				handle.node.setOpacity(1.0);
-			}else{
-				handle.node.setOpacity(OpaWhenNotSelect)
-			}
-		}
-
-		for(let handleName of Object.keys(this.rotationHandles)){
-			let handle = this.rotationHandles[handleName];
-
-			//if(this.activeHandle === handle){
-			//	handle.node.setOpacity(1.0);
-			//}else{
-			//	handle.node.setOpacity(OpaWhenNotSelect)
-			//}
-
-			handle.node.setOpacity(OpaWhenNotSelect);
-		}
-
-		for(let handleName of Object.keys(this.scaleHandles)){
-			let handle = this.scaleHandles[handleName];
-
-			if(this.activeHandle === handle){
-				handle.node.setOpacity(1.0);
-                if(!hideFocusHandles){
-                    let relatedFocusHandle = this.focusHandles[handle.name.replace("scale", "focus")];
-                    let relatedFocusNode = relatedFocusHandle.node;
-                    relatedFocusNode.setOpacity(OpaWhenNotSelect);
-                }
-				for(let translationHandleName of Object.keys(this.translationHandles)){
-					let translationHandle = this.translationHandles[translationHandleName];
-					translationHandle.node.setOpacity(OpaWhenNotSelect);
-				}
-
-				//let relatedTranslationHandle = this.translationHandles[
-				//	handle.name.replace("scale", "translation").replace(/[+-]/g, "")];
-				//let relatedTranslationNode = relatedTranslationHandle.node;
-				//relatedTranslationNode.setOpacity(OpaWhenNotSelect);
-
-
-			}else{
-				handle.node.setOpacity(OpaWhenNotSelect)
-			}
-		}
-
-		
-
-
-
-		if(handle){
-			handle.node.setOpacity(1.0);
-		}
-
-		
-	}
-
-	update () {
-
-		if(this.selection.length === 1){ 
-			this.scene.visible = true;
-
-			this.scene.updateMatrix();
-			this.scene.updateMatrixWorld();
-
-			let selected = this.selection[0];
-			let world = selected.matrixWorld;
-			let camera = this.viewer.scene.getActiveCamera();
-			let domElement = this.viewer.renderer.domElement;
-			let pointer = this.viewer.inputHandler.pointer;
-
-			let center = selected.boundingBox.getCenter(new THREE.Vector3()).clone().applyMatrix4(selected.matrixWorld);
-
-			this.scene.scale.copy(selected.boundingBox.getSize(new THREE.Vector3()).multiply(selected.scale));
-			this.scene.position.copy(center);
-			this.scene.rotation.copy(selected.rotation);
-
-			this.scene.updateMatrixWorld();
-
-			{ 
-				// adjust rotation handles
-				if(!this.dragging){
-					let tWorld = this.scene.matrixWorld;
-					let tObject = tWorld.clone().invert();
-					let camObjectPos = camera.getWorldPosition(new THREE.Vector3()).applyMatrix4(tObject);
-
-					let x = this.rotationHandles["rotation.x"].node.rotation;
-					let y = this.rotationHandles["rotation.y"].node.rotation;
-					let z = this.rotationHandles["rotation.z"].node.rotation;
-
-					x.order = "ZYX";
-					y.order = "ZYX";
-
-					let above = camObjectPos.z > 0;
-					let below = !above;
-					let PI_HALF = Math.PI / 2;
-
-					if(above){
-						if(camObjectPos.x > 0 && camObjectPos.y > 0){
-							x.x = 1 * PI_HALF;
-							y.y = 3 * PI_HALF;
-							z.z = 0 * PI_HALF;
-						}else if(camObjectPos.x < 0 && camObjectPos.y > 0){
-							x.x = 1 * PI_HALF;
-							y.y = 2 * PI_HALF;
-							z.z = 1 * PI_HALF;
-						}else if(camObjectPos.x < 0 && camObjectPos.y < 0){
-							x.x = 2 * PI_HALF;
-							y.y = 2 * PI_HALF;
-							z.z = 2 * PI_HALF;
-						}else if(camObjectPos.x > 0 && camObjectPos.y < 0){
-							x.x = 2 * PI_HALF;
-							y.y = 3 * PI_HALF;
-							z.z = 3 * PI_HALF;
-						} 
-					}else if(below){
-						if(camObjectPos.x > 0 && camObjectPos.y > 0){
-							x.x = 0 * PI_HALF;
-							y.y = 0 * PI_HALF;
-							z.z = 0 * PI_HALF;
-						}else if(camObjectPos.x < 0 && camObjectPos.y > 0){
-							x.x = 0 * PI_HALF;
-							y.y = 1 * PI_HALF;
-							z.z = 1 * PI_HALF;
-						}else if(camObjectPos.x < 0 && camObjectPos.y < 0){
-							x.x = 3 * PI_HALF;
-							y.y = 1 * PI_HALF;
-							z.z = 2 * PI_HALF;
-						}else if(camObjectPos.x > 0 && camObjectPos.y < 0){
-							x.x = 3 * PI_HALF;
-							y.y = 0 * PI_HALF;
-							z.z = 3 * PI_HALF;
-						} 
-                        
-                    }  
-                    
-				}
-
-
-                // adjust scale of components
-				for(let handleName of Object.keys(this.handles)){
-					let handle = this.handles[handleName];
-					let node = handle.node;
-
-					let handlePos = node.getWorldPosition(new THREE.Vector3());
-					let distance = handlePos.distanceTo(camera.position);
-					let pr = Utils.projectedRadius(1, camera, distance, domElement.clientWidth, domElement.clientHeight);
-
-					let ws = node.parent.getWorldScale(new THREE.Vector3());
-
-					let s = (ScaleRatio / pr);
-					let scale = new THREE.Vector3(s, s, s).divide(ws);
-    
-					let rot = new THREE.Matrix4().makeRotationFromEuler(node.rotation);     //需要使用到旋转,所以我把设置scale的移到旋转后了,否则在视图上下旋转的分界线处rotateHandel会被拉长从而闪烁。
-					let rotInv = rot.clone().invert();
-
-					scale.applyMatrix4(rotInv);
-					scale.x = Math.abs(scale.x);
-					scale.y = Math.abs(scale.y);
-					scale.z = Math.abs(scale.z);
-
-					node.scale.copy(scale);
-				}
-
-
-
-				{
-					let ray = Utils.mouseToRay(pointer, camera, domElement.clientWidth, domElement.clientHeight);
-					let raycaster = new THREE.Raycaster(ray.origin, ray.direction);
-					raycaster.layers.enableAll()//add
-                    
-                    let intersects = raycaster.intersectObjects(this.pickVolumes.filter(v => v.visible), true);
-                    
-                    
-                    
-                    
-					if(intersects.length > 0){
-						let I = intersects[0];
-						let handleName = I.object.handle;
-						this.setActiveHandle(this.handles[handleName]);
-					}else{
-						this.setActiveHandle(null);
-					}
-				}
-
-				// 
-				for(let handleName of Object.keys(this.scaleHandles)){
-					let handle = this.handles[handleName];
-					let node = handle.node;
-					let alignment = handle.alignment;
-
-					
-
-				}
-			}
-
-		}else{
-			this.scene.visible = false;
-		}
-		
-	}
-
-};

+ 0 - 313
src/objects/tool/Volume.js

@@ -1,313 +0,0 @@
-
-import * as THREE from "../../../libs/three.js/build/three.module.js";
-import {TextSprite} from "../TextSprite.js";
-
-export class Volume extends THREE.Object3D {
-	constructor (args = {}) {
-		super();
-
-		if(this.constructor.name === "Volume"){
-			console.warn("Can't create object of class Volume directly. Use classes BoxVolume or SphereVolume instead.");
-		}
-
-		//console.log(this);
-		//console.log(this.constructor);
-		//console.log(this.constructor.name);
-
-		this._clip = args.clip || false;
-		this._visible = true;
-	 
-		this._modifiable = args.modifiable || true;
- 
-
-		{ // event listeners
-			this.addEventListener('select', e => {});
-			this.addEventListener('deselect', e => {});
-		}
-
-	}
-
-	get visible(){
-		return this._visible;
-	}
-
-	set visible(value){
-		if(this._visible !== value){
-			this._visible = value;
-
-			this.dispatchEvent({type: "visibility_changed", object: this});
-		}
-	}
-
-	getVolume () {
-		console.warn("override this in subclass");
-	}
-
-	update () {
-		
-	};
-
-	raycast (raycaster, intersects) {
-
-	}
-
-	get clip () {
-		return this._clip;
-	}
-
-	set clip (value) {
-
-		if(this._clip !== value){
-			this._clip = value;
-
-			this.update();
-
-			this.dispatchEvent({
-				type: "clip_changed",
-				object: this
-			});
-		}
-		
-	}
-
-	get modifieable () {
-		return this._modifiable;
-	}
-
-	set modifieable (value) {
-		this._modifiable = value;
-
-		this.update();
-	}
-};
-
-
-export class BoxVolume extends Volume{
-
-	constructor(args = {}){
-		super(args);
-
-		this.constructor.counter = (this.constructor.counter === undefined) ? 0 : this.constructor.counter + 1;
-		this.name = 'box_' + this.constructor.counter;
-
-		let boxGeometry = new THREE.BoxGeometry(1, 1, 1);
-		boxGeometry.computeBoundingBox();
-
-		let boxFrameGeometry = new THREE.Geometry();
-		{
-			let Vector3 = THREE.Vector3;
-
-			boxFrameGeometry.vertices.push(
-
-				// bottom
-				new Vector3(-0.5, -0.5, 0.5),
-				new Vector3(0.5, -0.5, 0.5),
-				new Vector3(0.5, -0.5, 0.5),
-				new Vector3(0.5, -0.5, -0.5),
-				new Vector3(0.5, -0.5, -0.5),
-				new Vector3(-0.5, -0.5, -0.5),
-				new Vector3(-0.5, -0.5, -0.5),
-				new Vector3(-0.5, -0.5, 0.5),
-				// top
-				new Vector3(-0.5, 0.5, 0.5),
-				new Vector3(0.5, 0.5, 0.5),
-				new Vector3(0.5, 0.5, 0.5),
-				new Vector3(0.5, 0.5, -0.5),
-				new Vector3(0.5, 0.5, -0.5),
-				new Vector3(-0.5, 0.5, -0.5),
-				new Vector3(-0.5, 0.5, -0.5),
-				new Vector3(-0.5, 0.5, 0.5),
-				// sides
-				new Vector3(-0.5, -0.5, 0.5),
-				new Vector3(-0.5, 0.5, 0.5),
-				new Vector3(0.5, -0.5, 0.5),
-				new Vector3(0.5, 0.5, 0.5),
-				new Vector3(0.5, -0.5, -0.5),
-				new Vector3(0.5, 0.5, -0.5),
-				new Vector3(-0.5, -0.5, -0.5),
-				new Vector3(-0.5, 0.5, -0.5),
-
-			);
-
-		}
-
-		this.material = new THREE.MeshBasicMaterial({
-			color: 0x00ff00,
-			transparent: true,
-			opacity: 0.3,
-			depthTest: true,
-			depthWrite: false});
-		this.box = new THREE.Mesh(boxGeometry, this.material);
-		this.box.geometry.computeBoundingBox();
-		this.boundingBox = this.box.geometry.boundingBox;
-		this.add(this.box);
-
-		this.frame = new THREE.LineSegments(boxFrameGeometry, new THREE.LineBasicMaterial({color: 0x000000}));
-		// this.frame.mode = THREE.Lines;
-		this.add(this.frame);
-        
-        viewer.setObjectLayers(this, 'volume' )
-		this.update();
-	}
-
-	update(){
-		this.boundingBox = this.box.geometry.boundingBox;
-		this.boundingSphere = this.boundingBox.getBoundingSphere(new THREE.Sphere());
-
-		if (this._clip) {
-			this.box.visible = false;
-			 
-		} else {
-			this.box.visible = true;
-			 
-		}
-	}
-
-	raycast (raycaster, intersects) {
-		let is = [];
-		this.box.raycast(raycaster, is);
-
-		if (is.length > 0) {
-			let I = is[0];
-			intersects.push({
-				distance: I.distance,
-				object: this,
-				point: I.point.clone()
-			});
-		}
-	}
-
-	getVolume(){
-		return Math.abs(this.scale.x * this.scale.y * this.scale.z);
-	}
-
-};
-
-export class SphereVolume extends Volume{
-
-	constructor(args = {}){
-		super(args);
-
-		this.constructor.counter = (this.constructor.counter === undefined) ? 0 : this.constructor.counter + 1;
-		this.name = 'sphere_' + this.constructor.counter;
-
-		let sphereGeometry = new THREE.SphereGeometry(1, 32, 32);
-		sphereGeometry.computeBoundingBox();
-
-		this.material = new THREE.MeshBasicMaterial({
-			color: 0x00ff00,
-			transparent: true,
-			opacity: 0.3,
-			depthTest: true,
-			depthWrite: false});
-		this.sphere = new THREE.Mesh(sphereGeometry, this.material);
-		this.sphere.visible = false;
-		this.sphere.geometry.computeBoundingBox();
-		this.boundingBox = this.sphere.geometry.boundingBox;
-		this.add(this.sphere);
-
-		 
-
-		let frameGeometry = new THREE.Geometry();
-		{
-			let steps = 64;
-			let uSegments = 8;
-			let vSegments = 5;
-			let r = 1;
-
-			for(let uSegment = 0; uSegment < uSegments; uSegment++){
-
-				let alpha = (uSegment / uSegments) * Math.PI * 2;
-				let dirx = Math.cos(alpha);
-				let diry = Math.sin(alpha);
-
-				for(let i = 0; i <= steps; i++){
-					let v = (i / steps) * Math.PI * 2;
-					let vNext = v + 2 * Math.PI / steps;
-
-					let height = Math.sin(v);
-					let xyAmount = Math.cos(v);
-
-					let heightNext = Math.sin(vNext);
-					let xyAmountNext = Math.cos(vNext);
-
-					let vertex = new THREE.Vector3(dirx * xyAmount, diry * xyAmount, height);
-					frameGeometry.vertices.push(vertex);
-
-					let vertexNext = new THREE.Vector3(dirx * xyAmountNext, diry * xyAmountNext, heightNext);
-					frameGeometry.vertices.push(vertexNext);
-				}
-			}
-
-			// creates rings at poles, just because it's easier to implement
-			for(let vSegment = 0; vSegment <= vSegments + 1; vSegment++){
-
-				//let height = (vSegment / (vSegments + 1)) * 2 - 1; // -1 to 1
-				let uh = (vSegment / (vSegments + 1)); // -1 to 1
-				uh = (1 - uh) * (-Math.PI / 2) + uh *(Math.PI / 2);
-				let height = Math.sin(uh);
-
-				console.log(uh, height);
-
-				for(let i = 0; i <= steps; i++){
-					let u = (i / steps) * Math.PI * 2;
-					let uNext = u + 2 * Math.PI / steps;
-
-					let dirx = Math.cos(u);
-					let diry = Math.sin(u);
-
-					let dirxNext = Math.cos(uNext);
-					let diryNext = Math.sin(uNext);
-
-					let xyAmount = Math.sqrt(1 - height * height);
-
-					let vertex = new THREE.Vector3(dirx * xyAmount, diry * xyAmount, height);
-					frameGeometry.vertices.push(vertex);
-
-					let vertexNext = new THREE.Vector3(dirxNext * xyAmount, diryNext * xyAmount, height);
-					frameGeometry.vertices.push(vertexNext);
-				}
-			}
-		}
-
-		this.frame = new THREE.LineSegments(frameGeometry, new THREE.LineBasicMaterial({color: 0x000000}));
-		this.add(this.frame);
-
-		let frameMaterial = new THREE.MeshBasicMaterial({wireframe: true, color: 0x000000});
-		this.frame = new THREE.Mesh(sphereGeometry, frameMaterial);
-		//this.add(this.frame);
-
-		//this.frame = new THREE.LineSegments(boxFrameGeometry, new THREE.LineBasicMaterial({color: 0x000000}));
-		// this.frame.mode = THREE.Lines;
-		//this.add(this.frame);
-
-		this.update();
-	}
-
-	update(){
-		this.boundingBox = this.sphere.geometry.boundingBox;
-		this.boundingSphere = this.boundingBox.getBoundingSphere(new THREE.Sphere());
-
-		 
-	}
-
-	raycast (raycaster, intersects) {
-		let is = [];
-		this.sphere.raycast(raycaster, is);
-
-		if (is.length > 0) {
-			let I = is[0];
-			intersects.push({
-				distance: I.distance,
-				object: this,
-				point: I.point.clone()
-			});
-		}
-	}
-	
-	// see https://en.wikipedia.org/wiki/Ellipsoid#Volume
-	getVolume(){
-		return (4 / 3) * Math.PI * this.scale.x * this.scale.y * this.scale.z;
-	}
-
-};

+ 0 - 147
src/objects/tool/VolumeTool.js

@@ -1,147 +0,0 @@
-
-import * as THREE from "../../../libs/three.js/build/three.module.js";
-import {Volume, BoxVolume} from "./Volume.js";
-import {Utils} from "../../utils.js"; 
-
-export class VolumeTool extends THREE.EventDispatcher{
-	constructor (viewer) {
-		super();
-
-		this.viewer = viewer;
-		this.renderer = viewer.renderer;
-
-		this.addEventListener('start_inserting_volume', e => {
-			this.viewer.dispatchEvent({
-				type: 'cancel_insertions'
-			});
-		});
-
-		this.scene = new THREE.Scene();
-		this.scene.name = 'scene_volume';
-
-		this.viewer.inputHandler.registerInteractiveScene(this.scene);
-
-		this.onRemove = e => {
-			this.scene.remove(e.volume);
-		};
-
-		this.onAdd = e => {
-			this.scene.add(e.volume);
-		};
-
-		for(let volume of viewer.scene.volumes){
-			this.onAdd({volume: volume});
-		}
-
-		this.viewer.inputHandler.addEventListener('delete', e => {
-			let volumes = e.selection.filter(e => (e instanceof Volume));
-			volumes.forEach(e => this.viewer.scene.removeVolume(e));
-		});
-
-		viewer.addEventListener("update", this.update.bind(this));
-		viewer.addEventListener("render.pass.scene", e => this.render(e));
-		viewer.addEventListener("scene_changed", this.onSceneChange.bind(this));
-
-		viewer.scene.addEventListener('volume_added', this.onAdd);
-		viewer.scene.addEventListener('volume_removed', this.onRemove);
-	}
-
-	onSceneChange(e){
-		if(e.oldScene){
-			e.oldScene.removeEventListeners('volume_added', this.onAdd);
-			e.oldScene.removeEventListeners('volume_removed', this.onRemove);
-		}
-
-		e.scene.addEventListener('volume_added', this.onAdd);
-		e.scene.addEventListener('volume_removed', this.onRemove);
-	}
-
-	startInsertion (args = {}) {
-		let volume;
-		if(args.type){
-			volume = new args.type();
-		}else{
-			volume = new BoxVolume();
-		}
-		
-		volume.clip = args.clip || false;
-		volume.name = args.name || 'Volume';
-
-		this.dispatchEvent({
-			type: 'start_inserting_volume',
-			volume: volume
-		});
-
-		this.viewer.scene.addVolume(volume);
-		//this.scene.add(volume);
-
-		let cancel = {
-			callback: null
-		};
-
-		let drag = e => {
-			let camera = this.viewer.scene.getActiveCamera();
-			
-			
-            var I = e.intersect 
-			if (I) {
-				volume.position.copy(I.location);
-
-				let wp = volume.getWorldPosition(new THREE.Vector3()).applyMatrix4(camera.matrixWorldInverse);
-				// let pp = new THREE.Vector4(wp.x, wp.y, wp.z).applyMatrix4(camera.projectionMatrix);
-				let w = Math.abs((wp.z / 5));
-				volume.scale.set(w, w, w);
-			}
-		};
-
-		let drop = e => {
-			volume.removeEventListener('drag', drag);
-			volume.removeEventListener('drop', drop);
-
-			cancel.callback();
-		};
-
-		cancel.callback = e => {
-			volume.removeEventListener('drag', drag);
-			volume.removeEventListener('drop', drop);
-			this.viewer.removeEventListener('cancel_insertions', cancel.callback);
-		};
-
-		volume.addEventListener('drag', drag);
-		volume.addEventListener('drop', drop);
-		this.viewer.addEventListener('cancel_insertions', cancel.callback);
-
-		this.viewer.inputHandler.startDragging(volume);
-
-		return volume;
-	}
-
-	update(){
-		if (!this.viewer.scene) {
-			return;
-		}
-		
-		let camera = this.viewer.scene.getActiveCamera();
-		let renderAreaSize = this.viewer.renderer.getSize(new THREE.Vector2());
-		let clientWidth = renderAreaSize.width;
-		let clientHeight = renderAreaSize.height;
-
-		let volumes = this.viewer.scene.volumes;
-		for (let volume of volumes) {
-			 
-		}
-	}
-
-	render(params){
-		const renderer = this.viewer.renderer;
-
-		const oldTarget = renderer.getRenderTarget();
-		
-		if(params.renderTarget){
-			renderer.setRenderTarget(params.renderTarget);
-		}
-		renderer.render(this.scene, this.viewer.scene.getActiveCamera());
-		renderer.setRenderTarget(oldTarget);
-	}
-
-}

+ 0 - 723
src/objects/tool/ctrlPolygon.js

@@ -1,723 +0,0 @@
-import * as THREE from "../../../libs/three.js/build/three.module.js";
-import {LineDraw, MeshDraw} from "../../utils/DrawUtil.js";
-import math from "../../utils/math.js";
-
-
-
-
-
-
-const verticalLine = new THREE.Line3()
-
-//控制点和边的合集。具有可以拖拽修改的功能,拖拽时能防止线相交。
-export class ctrlPolygon extends THREE.Object3D { 
-    constructor (type, prop) {
-        super()
-        this.type = type
-        
-        this.maxMarkers = Number.MAX_SAFE_INTEGER;
-       
-         
-        this.transformData(prop);
-        for(let i in prop){
-            this[i] = prop[i]
-        }
-        
-        if(this.closed && this.dimension == '2d'){
-            this.areaPlane = this.createAreaPlane(); 
-            this.add(this.areaPlane)
-        }
-        
-        //数据--刚开始一定是空的
-        this.points = []; 
-        //mesh 不一定有
-        this.markers = []; 
-		this.edges = [];
-        
-        this.center
-        
-        
-        
-        
-    }
-    
-    initData(prop){
-        //开始加数据  
-        if(Potree.settings.editType == 'merge'){ //融合页面没有地图,measure的不需要指定datasetId,每个点都有各自的datasetId,跟着各自的模型走
-            if(this.dataset_points){
-                this.dataset_points = this.dataset_points.map(e=>{
-                    return e && new THREE.Vector3().copy(e) 
-                })
-                prop.points = this.dataset_points.map((p,i)=>{
-                    return Potree.Utils.datasetPosTransform({fromDataset:true, datasetId:this.points_datasets[i], position: p})
-                })
-                if(prop.points.some(e=>e == void 0)){
-                    return false
-                }               
-            }else{
-                this.dataset_points = []
-            }
-        } 
-        
-        
-        
-        if(prop.points){ 
-        
-            for(const p of prop.points){
-                const pos = new THREE.Vector3().copy(p) 
-                this.addMarker({point:pos}); 
-            }
-            
-            
-            if(Potree.settings.editType != 'merge'){ 
-                if(this.datasetId != void 0){//初始化位置
-                    if(this.dataset_points){
-                        this.dataset_points = this.dataset_points.map(e=>{
-                            return e && new THREE.Vector3().copy(e) 
-                        })
-                        this.transformByPointcloud() //根据dataset_points生成points  
-                    }  
-                }else{
-                    if(prop.dataset_points && prop.dataset_points.some(e=>e != void 0)){
-                        console.error('存在测量线的datasetId为空而dataset_points有值,请检查并删除:'+this.sid)//存在过的bug,原因未知,可能是后台处理dataset时替换的错误:http://192.168.0.21/index.php?m=bug&f=view&bugID=23601
-                        console.log(this)
-                    }
-                } 
-            }  
-            
-            this.getFacePlane()
-            this.getPoint2dInfo(this.points)
-            
-            this.update({ifUpdateMarkers:true})
-            //this.dragChange(new THREE.Vector3().copy(prop.points[prop.points.length-1]), prop.points.length-1); 
-            this.setSelected(false )
-            this.markers.forEach(marker=>{marker.dispatchEvent('addHoverEvent') })
-            return true
-        }
-    }
-    
-    
-    
-    
-    
-    addMarker(o={}){
-        var index = o.index == void 0 ? this.points.length : o.index  //要当第几个
-        
-        this.points = [...this.points.slice(0,index), o.point, ...this.points.slice(index,this.points.length)]
-		//this.points.push(o.point);
-         
-        if(o.marker){
-            this.add(o.marker)
-            this.markers = [...this.markers.slice(0,index), o.marker, ...this.markers.slice(index,this.markers.length)]
-            this.updateMarker(o.marker, o.point)
-            o.marker.addEventListener('drag', this.dragMarker.bind(this));
-            o.marker.addEventListener('drop', this.dropMarker.bind(this));
-            
-            
-            let addHoverEvent = (e)=>{
-                let mouseover = (e) => { 
-                    this.setMarkerSelected(e.object, 'hover', 'single'); 
-                    viewer.dispatchEvent({
-                        type : "CursorChange", action : "add",  name:"markerMove"
-                    }) 
-                };
-                let mouseleave = (e) => { 
-                    this.setMarkerSelected(e.object, 'unhover', 'single'); 
-                    viewer.dispatchEvent({
-                        type : "CursorChange", action : "remove",  name:"markerMove"
-                    })
-                } 
-                o.marker.addEventListener('mouseover', mouseover);
-                o.marker.addEventListener('mouseleave', mouseleave);
-                o.marker.removeEventListener('addHoverEvent',addHoverEvent) 
-            }
-            o.marker.addEventListener('addHoverEvent',addHoverEvent)//当非isNew时才添加事件
-            if(!this.isNew){
-                o.marker.dispatchEvent('addHoverEvent')
-            }
-            
-        } 
-        
-        if(o.edge){
-            this.add(o.edge)
-            this.edges = [...this.edges.slice(0,index), o.edge, ...this.edges.slice(index,this.edges.length)]
-        } 
-        
-        
-    }
-    
-    
-    
-    
-    dragMarker(e){
-        
-        var I, atMap 
-        
-        if(e.hoverViewport != e.drag.dragViewport){//不能使用e.dragViewport,要使用drag中的,因为drag中存储的要一直继承下来,不因mouseup了而改变。
-            viewer.dispatchEvent({
-                type : "CursorChange", action : "add",  name:"polygon_AtWrongPlace"
-            })
-            return
-        }
-        
-        viewer.dispatchEvent({
-            type : "CursorChange", action : "remove",  name:"polygon_AtWrongPlace"
-        })
-        
-        atMap = e.drag.dragViewport.name == 'mapViewport' 
-        
-        if(atMap && this.unableDragAtMap){ 
-            e.drag.object = null //取消拖拽
-            return 
-        }
-        e.drag.object.isDragging = true 
-        
-        
-        I = e.intersect && (e.intersect.orthoIntersect || e.intersect.location)
-        
-        //记录数据集
-        
-        //在三维中脱离点云(在map中拉到周围都没有点云的地方)的顶点,无法拖拽怎么办
-         
-        if (I) {  
-            let i = this.markers.indexOf(e.drag.object);
-            if (i !== -1) {  
-                this.dragChange(I.clone(), i, atMap) 
-                
-                /* if(this.points_datasets){
-                    if(e.intersect.pointcloud) this.points_datasets[i] = e.intersect.pointcloud.dataset_id
-                    else this.points_datasets[i] = null
-                } */ 
-                if(this.points_datasets){
-                    if(e.intersect.pointcloud) this.points_datasets[i] = e.intersect.pointcloud.dataset_id
-                    else if(e.intersect.object) this.points_datasets[i] = e.intersect.object.dataset_id
-                    else this.points_datasets[i] = null
-                }
-            }
-            this.editStateChange(true)
-            return true
-        }
-        
-        
-        
-        
-    };
-    
-    
-    
-    
-    
-    
-    dragChange(intersectPos, i, atMap){
-        let len = this.markers.length 
-        let oldPoint = this.points[i]; 
-        if(atMap){
-            intersectPos.setZ(oldPoint.z) //在地图上拖拽,不改变其高度。
-        }
-        let location = intersectPos.clone()
-        
-        
-        
-        if(this.faceDirection && this.maxMarkers == 2 && len == 2){//add 固定方向的点不直接拖拽
-            var p1 = this.markers[0].position
-            if(this.faceDirection == 'horizontal'){
-                var projectPos = location.clone().setZ(p1.z)
-            }else{
-                var projectPos = p1.clone().setZ(location.z)
-            }
-            //var p2 = p1.clone().add(this.direction)
-            //var projectPos = math.getFootPoint(location, p1, p2)
-            
-            
-            LineDraw.updateLine(this.guideLine, [location, projectPos])
-            location = projectPos
-            this.guideLine.visible = true
-        }else if( len > 1){ 
-             
-            var points = this.points.map(e=>e.clone())
-            points[i].copy(location) //算normal需要提前确认point
-            
-            //若为定义了面朝向的矩形
-            if(this.faceDirection == 'horizontal'){
-                if(len == 2){
-                    location.setZ(points[0].z) 
-                }
-                if(!this.facePlane){//一个点就能确定面
-                    this.facePlane = new THREE.Plane().setFromNormalAndCoplanarPoint( new THREE.Vector3(0,0,1), this.points[0]  )
-                }
-            }else if(this.faceDirection == 'vertical'){//当有两个点时, 有两个方向的可能
-                if(len == 2){
-                    if(this.isRect){
-                        let vec = points[0].clone().sub(location) 
-                        if(Math.sqrt(vec.x*vec.x+vec.y*vec.y) > Math.abs(vec.z) ){//水平(高度差小于水平距离时)
-                            location.setZ(points[0].z) 
-                            //this.cannotConfirmNormal = false;//能确定面为水平方向
-                        }else{//垂直 (当两点一样时也属于这种)
-                            location.setX(points[0].x);
-                            location.setY(points[0].y);
-                            //this.cannotConfirmNormal = true; //不能确定面,因第三点可绕着纵轴线自由移动
-                        }
-                    }
-                }else{ 
-                    {//判断cannotConfirmNormal. 如果前几段都在竖直线上,就不能固定出面方向。
-                        this.cannotConfirmNormal = true
-                        let max = this.isRect ? 1 : len-2 
-                        for(let i=0;i<max;i++){
-                            let p1 = points[i].clone()
-                            let p2 = points[i+1].clone()
-                            let vec = p1.sub(p2);
-                            if(vec.x != 0 || vec.y != 0){
-                                this.cannotConfirmNormal = false
-                                break;
-                            } 
-                        } 
-                    }
-                    
-                    if(!this.facePlane || this.cannotConfirmNormal){//三个点且为水平方向时,计算面
-                          
-                        var points_ = points.map(e=>new THREE.Vector2(e.x,e.y))
-                        var points2 = getDifferentPoint(points_, 2); 
-                        if(points2){
-                            let normal = math.getNormal2d({p1:points2[0], p2:points2[1]})  
-                            normal = new THREE.Vector3(normal.x, normal.y, 0)
-                            this.facePlane = new THREE.Plane().setFromNormalAndCoplanarPoint( normal, this.points[0]  )
-                        } 
-                    }
-                }
-            } 
-
-            if(len > 2){//area
-            
-                if(!this.faceDirection){ 
-                    if(len == 3 || this.isRect) this.cannotConfirmNormal = true //当第三个点固定后(有四个点时)才能固定面
-                    if(!this.facePlane || this.cannotConfirmNormal){
-                        var points3 = getDifferentPoint(points, 3);//只有找到三个不同的点算拥有面和area
-                        if(points3){
-                            this.facePlane = new THREE.Plane().setFromCoplanarPoints(...points3 )
-                        }
-                    }
-                }
-                
-                if( this.facePlane && !this.cannotConfirmNormal  ){//之后加的点一定要在面上  
-                    if(atMap){ 
-                        //地图上用垂直线,得到和面的交点。
-                        verticalLine.set(location.clone().setZ(100000), location.clone().setZ(-100000))//确保长度范围覆盖所有测量面 
-                        location = this.facePlane.intersectLine(verticalLine, new THREE.Vector3() )
-                        if(!location) return; 
-                    }else{ 
-                        location = this.facePlane.projectPoint(intersectPos, new THREE.Vector3() )
-                    }
-                }  
-                
-                
-                points[i].copy(location)//再copy确认一次
-                
-                if(this.isRect){ //是矩形 (即使没有faceDirection也能执行)
-                    //根据前两个点计算当前和下一个点
-                    var p1 = points[(i-2+len)%len]
-                    var p2 = points[(i-1+len)%len]
-                    if(p1.equals(p2)){//意外情况:重复点两次 ( bug点,改了好多遍)
-                        if(this.faceDirection == 'vertical'){
-                            p2.add(new THREE.Vector3(0,0,0.0001))
-                        }else{
-                            p2.add(new THREE.Vector3(0,0.0001,0))
-                        } 
-                    } 
-                    //p3 : location 
-                    var foot = math.getFootPoint(location, p1, p2)//p2 修改p2到垂足的位置
-                    var vec = foot.clone().sub(location)
-                    var p4 = p1.clone().sub(vec) 
-                     
-                    
-                    points[(i-1+len)%len].copy(foot) 
-                    points[(i+1)%len].copy(p4) 
-                    this.setPosition((i-1+len)%len, foot);//p2
-                    this.setPosition((i+1)%len, p4);
-                    
-                }  
-                
-                /* let points2d;
-                if(this.facePlane){
-                    var originPoint0 = points[0].clone() 
-                    var qua = math.getQuaBetween2Vector(this.facePlane.normal, new THREE.Vector3(0,0,1), new THREE.Vector3(0,0,1));
-                    points2d = points.map(e=>e.clone().applyQuaternion(qua))  
-                } */
-                this.getPoint2dInfo(points)
-                
-                var isIntersectSelf = !this.isRect && len > 3 && this.intersectSelf(this.point2dInfo.points2d)//检测相交
-                if(isIntersectSelf){
-                    //not-allowed
-                    viewer.dispatchEvent({
-                        type : "CursorChange", action : "add",  name:"polygon_isIntersectSelf"
-                    })
-                    this.isIntersectSelf = true
-                    return
-                }else{
-                    this.isIntersectSelf = false
-                    viewer.dispatchEvent({
-                        type : "CursorChange", action : "remove",  name:"polygon_isIntersectSelf"
-                    })
-                    /* this.facePlane && (this.point2dInfo = {
-                        originPoint0 ,
-                        points2d,
-                        quaInverse : qua.clone().invert()
-                    }) */
-                }
-                
-                
-                 
-            }
-            
-            var showGuideLine = len>1 && (this.faceDirection || len > 3)
-            if(showGuideLine && this.guideLine){
-                LineDraw.updateLine(this.guideLine, [intersectPos, location])
-                this.guideLine.visible = true
-            } 
-             
-            //console.log(this.points.map(e=>e.toArray())) 
-
-        } 
-         
-        
-        if(this.restrictArea){  
-            let holes = this.restrictArea.holes.concat(this.restrictArea.parentHoles)           
-            let holesPoints = holes.filter(e=>e!=this && e.points.length>2).map(e=>e.points) 
-            if(!math.isPointInArea(this.restrictArea.points, holesPoints, location)){
-                viewer.dispatchEvent({
-                    type : "CursorChange", action : "add",  name:"polygon_AtWrongPlace"
-                })
-                this.isAtWrongPlace = true
-                return
-            }
-            //就不处理相交线了。 有个缺点:floor上的hole可以限制room,但hole不受room限制,会导致room的marker被框在hole里而动不了。只能去调整hole了
-        } 
-        
-        
-        
-        viewer.dispatchEvent({
-            type : "CursorChange", action : "remove",  name:"polygon_AtWrongPlace"
-        })
-        this.isAtWrongPlace = false
-        this.setPosition(i, location); 
-        this.update()
-        
-        this.dispatchEvent({type:'dragChange', index:i})
-        
-        
-        
-    }
-    
-    dropMarker(e){
-        //console.log('dropMarker')
-        if (this.isNew && e.pressDistance>Potree.config.clickMaxDragDis){//拖拽的话返回
-            return this.continueDrag(null,e)   
-        } 
-        
-        if(e.isTouch){ 
-            if(e.hoverViewport != viewer.mainViewport && this.unableDragAtMap){
-                viewer.dispatchEvent({type:'reticule_forbit', v:true})
-                //console.log('reticule_forbit',true)
-                return this.continueDrag(null,e)    
-            }else{
-                viewer.dispatchEvent({type:'reticule_forbit', v:false})
-                //console.log('reticule_forbit',false)
-            }
-            this.dragMarker(e) //触屏时必须先更新下点 
-            
-        }
-        
-        
-        if (e.button != THREE.MOUSE.RIGHT && (//右键click的话继续执行,因为会停止
-                this.isIntersectSelf && this.isNew //有线相交了
-                || this.isAtWrongPlace && this.isNew
-                || !e.isAtDomElement && this.isNew//如果是刚添加时在其他dom点击, 不要响应
-                ||  e.hoverViewport != viewer.mainViewport && this.unableDragAtMap //垂直的测量线不允许在地图上放点
-                || this.isNew && !getDifferentPoint(this.points, this.points.length )   //不允许和之前的点相同, 但这句在点云稀疏时会导致难结束 
-            ) 
-        ){
-            return this.continueDrag(null,e)    
-        } 
-         
-        //console.log('drop marker' )
-         
-        let i = this.markers.indexOf(e.drag.object); 
-        if (i !== -1) {
-            this.dispatchEvent({
-                'type': 'marker_dropped', 
-                'index': i
-            });
-            if(this.markers.length>2 && this.facePlane)this.cannotConfirmNormal = false
-            this.guideLine &&(this.guideLine.visible = false)
-        }
-        
-       
-        
-        this.setMarkerSelected(e.drag.object, 'unhover', 'single') 
-        
-        this.editStateChange(false)
-        
-        
-        
-        
-        e.drag.endDragFun && e.drag.endDragFun(e)//  addmarker
-         
-        //if(this.changeCallBack)this.changeCallBack()
-           
-        return true
-    };
-    
-    getFacePlane(){//最普通一种get方法,根据顶点。且假设所有点已经共面,且不重合
-        if(this.points.length<3) return
-        this.facePlane = new THREE.Plane().setFromCoplanarPoints(...this.points.slice(0,3) )
-         
-    }
-    
-    getPoint2dInfo(points){ //在更新areaplane之前必须更新过point2dInfo
-        if(this.facePlane){ 
-            var originPoint0 = points[0].clone() 
-            var qua = math.getQuaBetween2Vector(this.facePlane.normal, new THREE.Vector3(0,0,1), new THREE.Vector3(0,0,1));
-            let points2d = points.map(e=>e.clone().applyQuaternion(qua))  
-        
-            this.point2dInfo = {
-                originPoint0 ,
-                points2d,
-                quaInverse : qua.clone().invert()
-            } 
-        }    
-    }
-    
-    
-    
-    
-    setPosition (index, position) {//拖拽后设置位置
-		let point = this.points[index];
-		point.copy(position);
-        /* if(this.datasetId){
-            this.dataset_points[index] = Potree.Utils.datasetPosTransform({toDataset:true, datasetId:this.datasetId, position:point.clone()})
-        } */
-        
-        /* if(Potree.settings.editType == 'merge'){ 
-            this.dataset_points[index] = Potree.Utils.datasetPosTransform({toDataset:true,this.points_datasets[i], position:point.clone()})
-        } */
-        
-        let marker = this.markers[index];  
-        this.updateMarker(marker, point)
- 
-	 
-	} 
-    
-    updateMarker(marker, pos){
-        marker.position.copy(pos);
-        marker.update();
-    }
-    
-    
-    intersectSelf(points2d){//add
-        var len =  points2d.length
-        for(var i=0;i<len;i++){
-            for(var j=i+2;j<len;j++){
-                if(Math.abs(j-len-i)<2)continue;//不和邻边比
-                
-                var p1 =  points2d[i]
-                var p2 =  points2d[i+1]
-                var p3 =  points2d[j]
-                var p4 =  points2d[(j+1)%len] 
-                if(p1.equals(p2) || p3.equals(p4) || p1.equals(p3) || p2.equals(p3) || p1.equals(p4) || p2.equals(p4))continue 
-             
-                
-                var line1 = [p1,p2]
-                var line2 = [p3,p4]
-                var intersect = math.isLineIntersect(line1, line2, false, 0.001)
-                if(intersect){
-                    return true
-                    break
-                } 
-            }
-        }
-          
-    }
-	
-    removeMarker (index) {
-        
-		this.points.splice(index, 1); 
-        
-        const marker = this.markers[index]
-		//this.remove(marker); 
-        this.markers.splice(index, 1);   
-        marker.dispatchEvent({type:'dispose'})
-        
-        
-		let edgeIndex = index           //(index === 0) ? 0 : (index - 1);
-        const edge = this.edges[edgeIndex]
-        if(edge){
-            this.remove(edge);
-            this.edges.splice(edgeIndex, 1);
-            edge.dispatchEvent({type:'dispose'})
-        }
-        this.point2dInfo && this.point2dInfo.points2d.splice(index, 1); //add
-
-        this.dispatchEvent({type:'removeMarker',index,marker})
-		
-        
-	} 
-    
-    createAreaPlane(mat){ 
-        var geometry = new THREE.Geometry();
-        var mesh = new THREE.Mesh(geometry, mat)
-        
-        return mesh
-    }
-    
-    updateAreaPlane(){
-        if(!this.point2dInfo)return
-        this.areaPlane.geometry.dispose()
-        if(this.points.length>2){
-            this.areaPlane.geometry = MeshDraw.getShapeGeo(this.point2dInfo.points2d)
-            var center = math.getCenterOfGravityPoint(this.point2dInfo.points2d) //重心 
-                  
-            var firstPos =  this.point2dInfo.points2d[0].clone()
-            firstPos.z = 0                  //因为shape只读取了xy,所以位移下, 再算出最终位置,得到差距
-            firstPos.applyQuaternion(this.point2dInfo.quaInverse)
-            var vec = this.point2dInfo.originPoint0.clone().sub(firstPos)
-            center = new THREE.Vector3(center.x, center.y, 0)
-            center.applyQuaternion(this.point2dInfo.quaInverse)
-            this.areaPlane.quaternion.copy(this.point2dInfo.quaInverse) 
-            this.areaPlane.position.copy(vec)       
-            center.add(vec)
-            this.center = center 
-        }else{
-            this.areaPlane.geometry = new THREE.Geometry()
-            
-        } 
-        
-        
-    }
-
-
-    
-    
-    
-     
-
-    update(options={}){
-        if(this.points.length === 0){
-			return;
-		} 
-        
-        
-        
-        
-        
-        let lastIndex = this.points.length - 1;
-            
-       
-        for (let index = 0; index <= lastIndex; index++) {
-            
-            let nextIndex = (index + 1 > lastIndex) ? 0 : index + 1;
-            let previousIndex = (index === 0) ? lastIndex : index - 1;
-
-            let point = this.points[index];
-            let nextPoint = this.points[nextIndex];
-            let previousPoint = this.points[previousIndex];
-
-            if(options.ifUpdateMarkers){
-                this.updateMarker(this.markers[index], point)
-            }   
-
-            { // edges
-                let edge = this.edges[index]; 
-                if(edge){
-                    LineDraw.updateLine(edge, [point, nextPoint]) 
-                    //edge.visible = index < lastIndex || this.isRect || (this.closed && !this.isNew);
-                }
-                
-                
-            }
-
-            
-             
-        }
-        
-        if(this.areaPlane){
-            this.updateAreaPlane() 
-        }
-        
-        //this.dispatchEvent({type:'update'})     
-        viewer.mapViewer && viewer.mapViewer.dispatchEvent('content_changed') //暂时先这么都通知
-        
-    } 
-    
-    dispose(){//add 
-        this.parent.remove(this)
-        this.markers.concat(this.edges).forEach(e=>e.dispatchEvent({type:'dispose'})) 
-    }
-    
-    
-    reDraw(restMarkerCount=0){//重新开始画
-        let pointCount = this.points.length - restMarkerCount // restMarkerCount为需要留下的marker数量
-        while(pointCount > 0){
-            this.removeMarker(--pointCount)
-        }
-        this.point2dInfo = null
-        this.facePlane = null   
-         
-        
-                    
-    }
-    
-    
-    setMarkerSelected(){}
-    editStateChange(state){
-        if(!state){
-            viewer.dispatchEvent({
-                type : "CursorChange", action : "remove",  name:"polygon_isIntersectSelf"
-            })
-            viewer.dispatchEvent({
-                type : "CursorChange", action : "remove",  name:"polygon_AtWrongPlace"
-            })
-            viewer.dispatchEvent({type:'reticule_forbit', v:false})
-            
-            this.markers.forEach(e=>e.isDragging = false )
-        }
-    }
-    
-    transformData(){}
-    setSelected(){}
-    
-    
-    
-    continueDrag(marker, e){
-        let object = marker || e.drag.object
-        object.isDragging = true 
-        var timer = setTimeout(()=>{//等 drag=null之后 //右键拖拽结束后需要重新得到drag 
-            if(this.parent && object.isDragging){
-                //console.log('continueDrag')        
-                viewer.inputHandler.startDragging( object ,
-                    {endDragFun: e.drag.endDragFun, notPressMouse:e.drag.notPressMouse, dragViewport:e.drag.dragViewport} 
-                )
-            } 
-        },1)
-        return timer
-    }
- 
-    
-}
-
-
-
-function getDifferentPoint(points, count){//for facePlane
-    var result = [];
-    for(let i=0;i<points.length;i++){
-        var p = points[i];
-        if(result.find(e=>e.equals(p)))continue;
-        else result.push(p)
-        if(result.length == count)break
-    }
-    if(result.length == count)return result
-}
-
-
- 
-
-
- 

+ 0 - 347
src/objects/tool/mapClipBox.js

@@ -1,347 +0,0 @@
-
-import * as THREE from "../../../libs/three.js/build/three.module.js";
-import {ctrlPolygon} from './ctrlPolygon.js'
-import {LineDraw } from "../../utils/DrawUtil.js";
-import Sprite from '../../objects/Sprite.js'
-import {config} from '../../settings.js'
-
-import math from "../../utils/math.js";
-let texLoader = new THREE.TextureLoader() 
-
-let color = new THREE.Color(config.clip.color)
-
-let markerMats
-let markerSizeInfo = {width2d:30}
-
-
-
-
-export class mapClipBox extends ctrlPolygon {
-    constructor (center, scale) { 
-        center = center.clone().setZ(0);//所有Z都为0
-        
-        
-        let prop = {
-            points : getPoints(center, scale, 0),
-            closed : true,
-            isRect : true,
-            dimension : '2d'
-        }
-         
-        
-        super('mapClipBox', prop)
-        
-        this.angle = 0
-        this.createRotateBar();
-        this.edgeMarkers = [];
-        
-        //addMarkers:
-        this.initData(prop)
-        
-        
-        
-        
-        {//areaPlane event 能拖动 
-            this.areaPlane.addEventListener('mouseover',()=>{ 
-                viewer.dispatchEvent({
-                    type : "CursorChange", action : "add",  name:"mapClipMove"
-                })  
-            })
-            this.areaPlane.addEventListener('mouseleave',()=>{ 
-                viewer.dispatchEvent({
-                    type : "CursorChange", action : "remove",  name:"mapClipMove"
-                })
-            })
-            
-            let lastPos;
-            let drag = (e)=>{
-                let intersect = e.intersect.orthoIntersect 
-                if(lastPos){ 
-                    let moveVec = new THREE.Vector3().subVectors(intersect, lastPos).setZ(0)
-                    this.center.add(moveVec)
-                    this.updatePoints()
-                    this.dispatchEvent({type:'repos'})
-                     
-                } 
-                lastPos = intersect.clone();                
-            }
-            let drop = (e)=>{
-                lastPos = null
-            }
-            this.areaPlane.addEventListener('drag', drag)
-            this.areaPlane.addEventListener('drop', drop)
-              
-        }
-        
-        
-        /* this.addEventListener('dragChange',()=>{
-            this.updateTwoMidMarker(index+1)
-        }) */
-        
-        
-        
-        viewer.setObjectLayers(this, 'mapObjects' )
-    }
-   
-   
-    
-    
-    
-    getScale(){
-        return new THREE.Vector3(this.points[0].distanceTo(this.points[1]), this.points[1].distanceTo(this.points[2]) ,1)
-    }
- 
-   
-    
-    addMarker(o={} ){
-        let marker = new Sprite({mat:this.getMarkerMaterial('default'), sizeInfo: markerSizeInfo, dontFixOrient: true, viewports:viewer.mapViewer.viewports, name:"mapClipBox_marker",   } )
-        
-        marker.renderOrder = 3 
-        //marker.markerSelectStates = {}
-        
-        let edge = LineDraw.createLine([new THREE.Vector3,new THREE.Vector3],{color  })
-        let edgeMarker = new Sprite({mat:this.getMarkerMaterial('default'), sizeInfo: markerSizeInfo, dontFixOrient: true, viewports:viewer.mapViewer.viewports, name:"mapClipBox_edgePoint"} )
-        let mouseover = (e) => {
-            this.setMarkerSelected(e.object, true, 'single');
-            viewer.dispatchEvent({
-                type : "CursorChange", action : "add",  name:"markerMove"
-            }) 
-        };
-        let mouseleave = (e) => {
-            this.setMarkerSelected(e.object, false, 'single'); 
-            viewer.dispatchEvent({
-                type : "CursorChange", action : "remove",  name:"markerMove"
-            })
-        }
-        edgeMarker.addEventListener('mouseover', mouseover);
-        edgeMarker.addEventListener('mouseleave', mouseleave);
-        let dragInfo = {lastPos:null};
-        edgeMarker.addEventListener('drag', this.dragEdge.bind(this,dragInfo));
-        edgeMarker.addEventListener('drop', this.dropEdge.bind(this,dragInfo));   
-        this.edgeMarkers.push(edgeMarker)
-        this.add(edgeMarker)
-        marker.dispatchEvent('addHoverEvent')  
-      
-        super.addMarker({point:o.point, marker:marker,  edge})
-        
-    }
-    
-    
-    
-    dragEdge(dragInfo, e){//拖拽一个边(或一个边类型的marker),带动它的两个端点。 可以转化为拖拽marker往法线方向
-        var I, atMap 
-         
-        atMap = e.dragViewport.name == 'mapViewport'
-        I = e.intersect.orthoIntersect 
-        
-        if (I && dragInfo.lastPos) {
-            let i = this.edgeMarkers.indexOf(e.drag.object);
-            if (i !== -1) {  
-                let lineNormal = math.getNormal2d({p1:this.points[i], p2:this.points[(i+1)%4]}); 
-                let moveVec = new THREE.Vector3().subVectors(I, dragInfo.lastPos).setZ(0)//移动的向量
-                let dragVec = moveVec.projectOnVector(lineNormal).setZ(0)//在法线上移动的向量
-                let newPos = new THREE.Vector3().addVectors(this.points[i], dragVec) //marker应到的位置
-                this.dragChange(newPos, i, atMap) //转化为这个marker的拖拽
-            }
-        }
-        dragInfo.lastPos = I.clone();  
-    }
-    dropEdge(dragInfo, e){
-        dragInfo.lastPos = null 
-        this.setMarkerSelected(e.drag.object, false, 'single') //拖拽时似乎没有触发mouseout
-    }
-    
-    
-    
-    createAreaPlane(){
-        var planeMat =  new THREE.MeshBasicMaterial({
-            color,//"#00eeff",
-            side:THREE.DoubleSide,
-            opacity:0.3,
-            transparent:true,
-            depthTest:false
-        })
-        
-        return super.createAreaPlane(planeMat)
-    }
-    
-    
-    
-    getMarkerMaterial(type) {
-        if(!markerMats){
-            markerMats = {  
-                default:    new THREE.MeshBasicMaterial({  
-                    transparent: !0,
-                    color,
-                    opacity: 0.8,
-                    map: texLoader.load(Potree.resourcePath+'/textures/whiteCircle.png' ),  
-                }),
-                select:    new THREE.MeshBasicMaterial({   
-                    transparent: !0,
-                    color,
-                    opacity: 1,
-                    map: texLoader.load(Potree.resourcePath+'/textures/whiteCircle.png' ), 
-                     
-                }),   
-            }
-            mapClipBox.markerMats = markerMats
-        }
-        return markerMats[type]
-        
-    }
-    
-    setMarkerSelected(marker, state, hoverObject){ 
-        //console.warn(marker.id , state, hoverObject)
-        if(state == 'hover'){
-            marker.material = this.getMarkerMaterial('select')
-        }else{
-            marker.material = this.getMarkerMaterial('default')
-        }
-        
-        /* marker.markerSelectStates[hoverObject] = state
-        let absoluteState = false
-        for(var i in marker.markerSelectStates){
-            if(marker.markerSelectStates[i]){
-                absoluteState = true; break;
-            }
-        }
-        if(absoluteState){
-            marker.material = this.getMarkerMaterial('select')
-        }else{
-            marker.material = this.getMarkerMaterial('default')
-        }
-        
-        marker.selected = absoluteState */
-        
-        viewer.mapViewer.dispatchEvent('content_changed') 
-    }
-    
-    createRotateBar(){
-        //中心点在线的一端,整体初始在box上方
-        const lineLen = 1.5, circleWidth = 2, barOpacity = 0.7;
-       
-        let object = new THREE.Object3D;
-        
-        let bar = new Sprite({mat:new THREE.MeshBasicMaterial({ 
-                side:THREE.DoubleSide,
-                opacity: barOpacity,
-                transparent:true,
-                depthTest:false, 
-                map: texLoader.load(Potree.resourcePath+'/textures/rotation_circle.png' ), 
-            }) ,
-            root:object,
-            sizeInfo: markerSizeInfo, 
-            dontFixOrient: true,
-            viewports:viewer.mapViewer.viewports,
-            name:"mapClipRotateBar"
-        })
-        bar.position.set(0,lineLen+circleWidth/2,0)
-        bar.scale.set(circleWidth,circleWidth,circleWidth)
-        
-        bar.addEventListener('mouseover',()=>{
-            bar.material.opacity = 1
-            viewer.dispatchEvent({
-                type : "CursorChange", action : "add",  name:"mapClipRotate"
-            })
-            viewer.mapViewer.dispatchEvent('content_changed') 
-        })
-        
-        let leave = ()=>{ 
-            bar.material.opacity = barOpacity
-            viewer.dispatchEvent({
-                type : "CursorChange", action : "remove",  name:"mapClipRotate"
-            })
-            viewer.mapViewer.dispatchEvent('content_changed') 
-            
-        } 
-        bar.addEventListener('mouseleave',leave)
-        this.addEventListener('dispose', leave)    
-        
-        let lastPos;
-        bar.addEventListener('drag',(e)=>{
-            var intersect = e.intersect.orthoIntersect   
-            if(lastPos){ 
-                let vec1 = new THREE.Vector3().subVectors(lastPos, this.center).setZ(0)
-                let vec2 = new THREE.Vector3().subVectors(intersect, this.center).setZ(0)
-                let angle = math.getAngle(vec1,vec2,'z')  
-                this.angle += angle 
-                this.rotateBar.rotation.z = this.angle
-                this.updatePoints() 
-                this.dispatchEvent({type:'rotate', angle: this.angle})
-            }
-            lastPos = intersect.clone();       
-        })
-        bar.addEventListener('drop',()=>{
-            lastPos = null 
-            viewer.dispatchEvent({
-                type : "CursorChange", action : "remove",  name:"mapClipRotate"
-            })
-        })
-        
-        let line = LineDraw.createLine([new THREE.Vector3, new THREE.Vector3(0,lineLen,0)],{color})
-        
-        
-        object.add(bar)
-        object.add(line) 
-        this.add(object)
-        this.rotateBar = object
-        this.rotateBar.bar = bar
-    }
-    
-    updatePoints(scale){
-        this.points = getPoints(this.center, scale || this.getScale(), this.angle)
-        this.getPoint2dInfo(this.points)
-        this.update({ifUpdateMarkers:true}) 
-    }
-    
-    update(options={}){ 
-        super.update(options)
-        
-        {//update rotateBar
-            let center = new THREE.Vector3().addVectors(this.points[0], this.points[1]).multiplyScalar(0.5); 
-            this.rotateBar.position.copy(center) 
-            this.rotateBar.bar.update()//更新sprite matrix
-        }
-        {
-            for(let i=0;i<4;i++){
-                let current = this.points[i];
-                let next = this.points[(i+1)%4];
-                let mid = new THREE.Vector3().addVectors(current, next).multiplyScalar(0.5)
-                
-                this.updateMarker(this.edgeMarkers[i], mid)
-            }
-            
-            
-        }
-        
-        
-    }
-    
-    dispose(){
-        super.dispose()
-        this.dispatchEvent('dispose')
-        
-    }
-     
-}
-
-
-
-
-
-
-function getPoints(center, scale, angle=0){  
-    let points = [
-        new THREE.Vector3(-scale.x/2, +scale.y/2, 0),  
-        new THREE.Vector3(+scale.x/2, +scale.y/2, 0), 
-        new THREE.Vector3(+scale.x/2, -scale.y/2, 0),  
-        new THREE.Vector3(-scale.x/2, -scale.y/2, 0),     
-    ] 
-    var rotMatrix = new THREE.Matrix4().makeRotationAxis(new THREE.Vector3(0,0,1), angle)//再旋转 
-    points.forEach(e=>{
-        e.applyMatrix4(rotMatrix) 
-        e.add(center) 
-    })
-    return points
-}
- 

+ 0 - 449
src/settings.js

@@ -1,449 +0,0 @@
-//xzw add  
-import browser from './utils/browser.js'
-
-const config = {//配置参数   不可修改
-    displayMode:{ 
-		showPointCloud:{
-			atPano:{
-                showPoint : true,
-                showSkybox: false,
-                pointUsePanoTex : false 
-                
-			},
-            transition:{
-                showPoint: true,
-                showSkybox: false,
-                pointUsePanoTex: false  
-            },
-            canLeavePano: true   //是否能离开pano位置 
-		},
-
-		showPanos:{
-            atPano:{
-                showPoint : false,
-                showSkybox: true,
-                pointUsePanoTex : false  
-			},
-            transition:{
-                //showPoint: true,
-                showSkybox: true,
-                //pointUsePanoTex: true //是否使用全景贴图
-            },
-            canLeavePano: false    
-		}, 
-        
-		showBoth:{
-            atPano:{
-                showPoint : true,
-                showSkybox: true,
-                pointUsePanoTex : false //?  
-			},
-            transition:{
-                showPoint: true,
-                showSkybox: true,
-                pointUsePanoTex: true  
-            },
-            canLeavePano: true   //是否能离开pano位置   离开后自动变为showPointCloud
-		},
-        //test:
-        pointUsePanoTex:{ //---静止时调点云
-            atPano:{
-                showPoint : true,
-                showSkybox: false,
-                pointUsePanoTex : true  
-			},
-            transition:{
-                showPoint: true,
-                showSkybox: true,
-                pointUsePanoTex: true //是否使用全景贴图
-            },
-            canLeavePano: false    
-		},
-
-	},
-    
-    
-    
-    urls:{
-        //localTextures:'../resources/textures/', 
-        prefix1: 'https://laser-oss.4dkankan.com',//oss
-        prefix2: 'https://testlaser.4dkankan.com',
-        prefix3: 'https://4dkk.4dage.com',
-        prefix4: 'https://uat-laser.4dkankan.com',//test.4dkankan
-        prefix5: 'https://laser.4dkankan.com',
-        prefix6: 'https://mix3d.4dkankan.com/backend',
-        
-    },
-     
-    /* transitionsTime:{
-        flyTime : 1000  // 毫秒/米
-        panoToPano: 1000, 
-        flyIn:1000,
-        flyOut:1000,
-    } */
-    transitionsTime:{
-        flyMinTime : 500 /* * 3 */,  // 毫秒/米
-        flytimeDistanceMultiplier: 150/* * 3  */,
-        panoToPanoMax: 2000/*  * 3 */, 
-        flyIn:1000,
-        flyOut:1000
-    }
-    
-    ,
-    moveSpeedAdujust : 0.5  //越小越慢
-    ,
-    view:{
-        fov:70,  //navvis:50 
-        near:0.1,
-        far: 10000,
-    },
-    
-    map:{//mapViewer
-        mapHeight : -1000,//要比点云低。最低
-        cameraHeight : 1000,  //最高  ,注意(如sitemodel)其他的物体不能超过这个高度
-    },
-    
-    
-    pointDensity:{
-        magnifier:{  
-            maxLevelPercent: 1,
-            pointBudget : 8*1000*1000, 
-        },
-        panorama:{//显示全景时的漫游。因为点只能显示1个像素的大小,所以必须很密集,但又要限制点的数量
-            maxLevelPercent: 0.6,
-            pointBudget : /* 4*1000*1000// */browser.isMobile() ?  0.1*1000*1000 :  0.4*1000*1000,  //点云总最大数
-        }, 
-        
-        fourViewports:{//分四屏时防止卡顿
-            maxLevelPercent: 0.4,  
-            pointBudget :1*1000*1000, // 只要限制这个就足够 (为什么分屏focus区域不同会闪烁,navvis不会)(navvis:maxLevel:5,pointBudget:1*1000*1000)
-        }, 
-        fourViewportsMain:{//分四屏时防止卡顿
-            maxLevelPercent: 0.8,  
-            pointBudget :1*1000*1000, // 只要限制这个就足够 (为什么分屏focus区域不同会闪烁,navvis不会)(navvis:maxLevel:5,pointBudget:1*1000*1000)
-        }   
-        ,
-        panoEdit:{
-            maxLevelPercent: 1,  //在远处时由于pointBudget限制而展示稀疏,凑近时就变为最高质量了
-            pointBudget :1*1000*1000, //避免卡顿
-        },
-        
-        low:{//highPerformance
-            maxLevelPercent: 0.4, //最小为0
-            percentByUser:true, //如果用户定义了percent,使用用户的
-            pointBudget : 1*1000*1000,
-        }, 
-        middle:{//balanced  //不同场景相同级别所产生的numVisibleNodes和numVisiblePoints不同,如果分层比较细,可能要到level8才能看清,那么level5看到的点就很大且很少,如隧道t-e2Kb2iU
-            maxLevelPercent: 0.7,
-            percentByUser:true,
-            pointBudget:browser.isMobile() ? 4*1000*1000 : 2*1000*1000, 
-        },
-        high:{//highQuality
-            maxLevelPercent: 1, 
-            percentByUser:true,
-            pointBudget:browser.isMobile() ? 8*1000*1000 : 4*1000*1000,
-        }
-        //browser.isMobile() 时要不要限制下pointBudget,还是让用户自己调低质量?
-        //minNodeSize?
-        //数值由testLevelSteps得来,其中nodeMaxLevel为2时,low和middle的都是1,如果真有这么低的点云就单独处理下。
-        //多个viewport尽量保证pointBudget一样,或者pointBudget不能太低于所需,否则会反复加载了又清除
-    },  
-     
-    
-     
-    clip:{
-        color: '#FFC266', //map
-        
-    },
-    panoFieldRadius : 10, //当前位置多远范围内可以切全景模式
-    
-    measure:{
-        color:'#00C8AF',
-        default:{
-            color:"#64C8BB",//"#00c7b2",
-            opacity:0.7
-        },
-        highlight:{
-            color:'#00C8AF',//"#00c7b2",
-            opacity:1
-        },
-        guide:{
-            color:'#FFFFFF', 
-            opacity:1
-        }
-        ,   
-        backColor:'#333333',
-         
-        lineWidth: 4,
-       
-        textColor: "#FFFFFF"
-        
-    },
-    material:{//初始化
-        pointSize: 0.1,  
-        realPointSize : 0.1,//实际上的ui滑动条默认大小(兼容旧的版本)
-        minSize: 0.1,
-        maxSize: 10000,
-        pointSizeType: 'ATTENUATED', //'ADAPTIVE'//'ADAPTIVE' \ FIXED //ADAPTIVE的在小房间里大小会不太匹配,但在远景似乎更好
-        /* 
-            ATTENUATED : 衰减   真实大小,靠近时感觉是点云一点点变多,缝隙变小
-            ADAPTIVE:  自适应   大小根据level变化,越高越小。靠近时感觉点云由大慢慢细分成小份。这个感觉更佳但是navvis为何不用这个
-         */
-        
-        absolutePanoramaSize: 1.3 ,//全景漫游时的size  是fixed的模式
-        
-        //sizeAtPanoRtEDL : 2000,  
-        pointColor:'#ffffff',
-        
-        
-        //sizeAddAtPanoRtEDL : 0.5, //全景模式静止时的size
-        //ADAPTIVE : 字会失真扭曲
-        //'ATTENUATED' 往旁边看有缝隙、点在浮动
-        //navvis的shader在哪里 为什么不会抖动
-    }
-    ,
-     
-    
-    renderLayers:{//渲染层,方便分批渲染管理,替代scene的创建。数字不代表顺序。(数字不能太大)
-        bg: 20, 
-        bg2: 21,
-        
-        skybox: 1,
-        pointcloud: 11,
-        sceneObjects:0,//default
-        model : 2,   
-        
-        measure:4,  
-        magnifier:5, 
-        magnifierContent:16,
-        volume:6,
-        transformationTool:7,
-       
-        map:8,
-        mapObjects:9,//default
-        
-         
-        bothMapAndScene: 3,
-        
-        siteModeOnlyMapVisi:12,//只能mapViewer可见
-        siteModelMapUnvisi:13,//只有mapViewer不可见
-        siteModeSideVisi:14,//只有侧面可见
-        
-        
-        layer1: 10,// 备用1
-        layer2: 15,// 备用2
-    },
-    
-    renderOrders:{ //会影响到绘制、pick时的顺序。
-        model:10
-    }, 
-    siteModel:{
-        names:{
-            'building': '建筑',
-            'floor':'楼层',
-            'room':'房间'
-        },
-        floorHeightDefault: 5,//一层楼的高度
-        
-        
-    },
-    
-    panosEdit:{
-         
-    },
-     
-    tiling: {
-        panoPreRenderRepeatDelay: 2500,
-        panoPreRenderDelay: 500,
-        preRenderTourPanos: browser.valueFromHash("tileprerender", 0),
-        tilingFlagNames: ["usetiles", "tiles"],
-        maxNavPanoQuality: browser.valueFromHash("maxtileq", null),
-        maxZoomPanoQuality: browser.valueFromHash("maxztileq", null),
-        overlayStyle: browser.valueFromHash("tileoverlay", 0),
-        uploadIntervalDelay: browser.valueFromHash("tileupdelay", 10),
-        initialIntervalDelay: browser.valueFromHash("itiledelay", 0),
-        maxNonBaseUploadsPerFrame: browser.valueFromHash("maxnbtpf", 2),
-        maxBaseUploadsPerFrame: browser.valueFromHash("maxbtpf", 6),
-        customCompression: browser.valueFromHash("tilecustcomp", 0),
-        mobileHighQualityOverride: !1,
-        allowUltraHighResolution: !0
-    },
-    navigation: {
-        panoScores: !1,
-        mouseDirection: !0,
-        filterStrictness: .75,
-        angleFactor: -30,
-        directionFactor: 10,
-        distanceFactor: -1,
-        optionalityFactor: 3
-    } 
-    ,
-    axis : {   'x':{color:'#d0021b'/* 'red' */}, 'y':{ color:'#86c542' /* 'green' */},  'z': {color:'#3399c8' /* 'blue' */}},  
-    
-    
-    highQualityMaxZoom: 2,
-    ultraHighQualityMaxZoom: 3,
-    
-    clickMaxDragDis:5,
-    clickMaxPressTime:500, //ms
-    doubleClickTime:200,//双击间隔时间
-     
-     
-    background: '#232323',
-    mapBG:'#F5F5F5', //地图的clearColor
-
-    colors: {  //from navvis
-        red:  [213,0,0],
-        pink:  [197,17,98],
-        purple: [170,0,255],
-        "deep purple": [98,0,234],
-        blue: [ 41,98,255],
-        "light blue": [ 0,145,234],
-        cyan: [ 0,184,212],
-        teal: [ 0,191,165],
-        green: [0,200,83],
-        "light green": [ 100,221,23],
-        lime: [ 174,234,0],
-        yellow: [ 255,214,0],
-        amber: [ 255,171,0],
-        orange: [ 255,109,0],
-        "deep orange": [ 255,61,0],
-         
-    },
-}
-
-
-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  }
-        }  
-    },
-    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
-    }
-    
-}
-
-
-
-/* 显示模式:
-
-1只显示点云: 滚轮为前进后退,方向键可以行走。进入漫游点时自动变为混合(这样全景可以弥补缝隙),过渡时只显示点云。
-2只显示全景: 不能任意行走。 过渡时显示贴图材质非edl的点云(否则有折痕不贴合)。
-3混合:都显示。 不能任意行走。过渡时显示贴图材质非edl的点云(因为只显示点云的话不太美,点云很碎,不细腻)
- */
-window.testLevelSteps = function(steps){//[0.4,0.7,1]
-    if(!steps){
-        let s = Potree.config.pointDensity;
-        steps = [s.low.maxLevelPercent, s.middle.maxLevelPercent, s.high.maxLevelPercent, ]
-    }
-    let max = 1
-    while(++max<=12){ 
-        let r1 = steps.map(e=>e * max);
-        let r2 = steps.map(e=>Math.round(e * max));
-        console.log(`当nodeMaxLevel为${max}时,每一级的level分别为${r2}, (小数:${r1})`) 
-    }
-    console.log('请检查每一层的三个level是否有重复')
-     
-} 
-function getPrefix(){  
-    let u = window.location.href.split('//')
-    let v = u[1].split('/');
-    return v[0]
-}
-
- 
-let settings = {//设置   可修改
-    editType : '',
-    number: '', //场景序号
-    originDatasetId:'',//场景原本的数据集id,应该就是数据集第一个吧
-    isOfficial:false,
-    webSite:'testdata',//正式:'datav1', //不同环境对应的静态文件的地址不同
-     
-    isLocal:false, //是否本地 局域网版本
-    libsUrl:'../libs/',
-    displayMode:'',
-    isTest :browser.urlHasValue('test'),
-    prefix: getPrefix(),
-    pointDensity: '',    UserPointDensity:'',//pointDensity会随着进入不同的模块而自动改变,UserPointDensity记录了用户的设置
-    UserDensityPercent:null,//点云密度百分比 
-    ifShowMarker:true,//显示漫游点
-    floorplanType:{},//平面图类型 'default' | 'diy'  不同数据集不同{datasetId:...}
-    floorplanEnable:false,
-    floorplanEnables:{},
-    floorplanRequests:{},//开始加载了的
-    
-    mapEnable:true,//地图区域是否加载地图
-    cameraFar : config.view.far, //相机最远范围 1-300
-    //limitFar: true, //是否使用setting的cameraFar来限制(如在点云裁剪时为false)
-    showPanoMesh:false, //显示小球,
-    dblToFocusPoint:false,//调试时如果需要双击飞向某个点云的点,就打开。此时不在漫游点的话单击将无法漫游。//因和单击漫游冲突 
-    
-    unableNavigate : false,//进入如裁剪界面时 禁止漫游
-    sizeFitToLevel: false,//当type为衰减模式时自动根据level调节大小。每长一级,大小就除以2
-    zoom:{
-        enabled : true,
-        min:1,
-        max: config.highQualityMaxZoom,
-        activationThreshold: 1.1,
-    },
-    navConstantly:true,
-    navTileClass: browser.isMobile() ? '1k' : '2k',  //默认加载到
-    tileClass:'4k',     //最高可达
-    /* loadTilesWhenUnfocus:false, //页面unfocus时也仍在加载tiles
-    loadPointsWhenUnfocus:true, //页面unfocus时也仍在加载点云 */
-   
-    //initialShowPano:true
-    drawEntityData: false,
-    
-    zoomFromPointert:{//定点缩放(包括点云模式、全景模式、地图)
-        whenPanos:true,
-        whenPointCloud:true,
-        map:true,
-    },
-    rotAroundPoint:true,//点云模式是否能绕intersectPoint旋转
-    tourTestCameraMove:false, //测试镜头时,不移动真实的镜头, 只移动frustum
-    cameraAniSmoothRatio : 20, //镜头动画平滑系数,越高越平滑
-    urls  : $.extend({}, config.urls, {
-        prefix : config.urls.prefix4 //主要使用的 是测试环境,根据不同工程更改
-    }), 
-    
-    
-    useDepthTex: true,//使用深度贴图,但不代表一定有(得到的intersect更快速准确和稳定)   SS-t-7DUfWAUZ3V  
-    //matUseDepth:false, 
-    //panoEdit:
-    datasetsPanos:{},
-    
-    //mergeModel:
-    boundAddObjs:false,
-    intersectOnObjs:false,
-    intersectWhenHover:true,
-
-    notAdditiveBlending:false, //点云是否使用普通的blend, 否则会曝光过渡
-    precision:2  // 两位小数
-}
- 
- 
-
-//JSON.parse(localStorage.getItem('setting'))
-
-settings.isLocalhost = settings.prefix.includes('localhost')
-
-
-/* 
-    关于maxLevel:
-    viewer.scene.pointclouds[0].root.getLevel() 是 0
-    hierarchyStepSize是什么?见 if ((this.level % this.pcoGeometry.hierarchyStepSize) === 0 && this.hasChildren
- 
- 
- */
- 
- 
-export {config, settings}

+ 0 - 897
src/start.js

@@ -1,897 +0,0 @@
-import * as THREE from "../libs/three.js/build/three.module.js";
-import {settings, config} from './settings.js' 
-import math from './utils/math.js' 
-import browser from './utils/browser.js' 
-import './custom/three.shim.js' 
- 
-import {Utils} from "./utils.js"
-import "./custom/potree.shim.js"
- 
-
-var start = function(dom, mapDom, number ){ //t-Zvd3w0m
-    /* {
-        let obj = JSON.parse(localStorage.getItem('setting'))
-        for(let i in obj){
-            console.log(i + ': ' +  obj[i])
-        }
-    }
-     */ 
-    Potree.settings.number = number || 't-o5YMR13'// 't-iksBApb'// 写在viewer前
-    
-    
-     
-    
-    let viewer = new Potree.Viewer(dom , mapDom);
-    
-    let Alignment = viewer.modules.Alignment
-    
-    
-    //let pointDensity = config.pointDensity.middle
-	viewer.setEDLEnabled(false);
-    viewer.setFOV(config.view.fov);
-    //viewer.setPointBudget(pointDensity.pointBudget);
-    viewer.loadSettingsFromURL(); 
-    
-    
-    if(!Potree.settings.isOfficial){ 
-        viewer.loadGUI(() => {
-            viewer.setLanguage('en');
-            //$("#menu_appearance").next().show();
-            $("#menu_tools").next().show();
-            $("#menu_scene").next().show();
-            $("#siteModel").show();
-            //$("#alignment").show();
-            viewer.toggleSidebar();
-        });
-        Potree.settings.sizeFitToLevel = true//当type为衰减模式时自动根据level调节大小。每长一级,大小就除以2
-    }
-
-    Potree.loadDatasetsCallback = function(data, ifReload){
-        if(!data || data.length == 0)return console.error('getDataSet加载的数据为空')
-           
-        Potree.datasetData = data
-        viewer.transform = null
-        var datasetLength = data.length 
-        var pointcloudLoaded = 0
-        var panosLoaded = 0
-        var pointcloudLoadDone = function(){//点云cloud.js加载完毕后 
-            viewer.updateModelBound()
-            let {boundSize, center} = viewer.bound
-           
-            Potree.Log(`中心点: ${math.toPrecision(center.toArray(),2)}, boundSize: ${math.toPrecision(boundSize.toArray(),2)} ` , null, 12)
-            
-            if(!Potree.settings.isOfficial){
-                Potree.loadMapEntity('all') //加载floorplan 
-            }
-            
-            
-            if(!ifReload){    
-                viewer.scene.view.setView({ 
-                    position: center.clone().add(new THREE.Vector3(10,5,10)), 
-                    target: center
-                })
-                 
-                viewer.dispatchEvent({type:'loadPointCloudDone'})
-            
-                if(!Potree.settings.UserPointDensity){
-                    Potree.settings.UserPointDensity = 'high'//'middle' 
-                }
-                 
-                Potree.Log('loadPointCloudDone  点云加载完毕', null, 10)  
-            }    
-            
-        }
-        
-        
-        var panosLoadDone = function(){   
-            
-            
-            viewer.images360.loadDone() 
-            viewer.scene.add360Images(viewer.images360); 
-            viewer.mapViewer.addListener(viewer.images360)
-            
-            
-            {//初始位置 
-                var urlFirstView = false
-                var panoId = browser.urlHasValue('pano',true);
-                if(panoId !== ''){
-                    var pos
-                    var pano = viewer.images360.panos.find(e=>e.id==panoId);
-                    if(pano){
-                        viewer.images360.focusPano({
-                            pano,
-                            duration:0, 
-                            callback:()=>{/* Potree.settings.displayMode = 'showPanos' */}
-                        })
-                          
-                    }
-                }else{//考虑到多数据集距离很远,或者像隧道那种场景,要使视野范围内一定能看到点云,最好初始点设置在漫游点上
-                    
-                    let {boundSize, center} = viewer.bound
-                    
-                    let pano = viewer.images360.findNearestPano(center)
-                     
-                    /* pano && viewer.scene.view.setView({ 
-                        position: pano.position.clone().add(new THREE.Vector3(10,10,10)), 
-                        target: pano.position
-                    }) */
-                     
-                    pano && viewer.images360.flyToPano({
-                        pano,  duration:0,
-                        target : viewer.images360.bound.center     
-                    })
-                    
-                    
-                } 
-            }
-            
-            
-            
-            viewer.addVideo()//addFire()
-            
-            console.log('allLoaded')
-            viewer.dispatchEvent('allLoaded')
-        }
-        
-        var transformPointcloud = (pointcloud, dataset)=>{
-            var locationLonLat = dataset.location.slice(0,2)
-            //当只有一个dataset时,无论如何transform 点云和漫游点都能对应上。
-            var location = viewer.transform.lonlatToLocal.forward(locationLonLat)  //transform.inverse()
-            //初始化位置 
-            
-            viewer.sidebar && viewer.sidebar.addAlignmentButton(pointcloud) 
-            
-            //dataset.orientation = 0
-            
-            Alignment.rotate(pointcloud, null, dataset.orientation)   
-            Alignment.translate(pointcloud, new THREE.Vector3(location[0], location[1], dataset.location[2])) 
-            
-            pointcloud.updateMatrixWorld()
-            
-            
-            Potree.Log(`点云${pointcloud.dataset_id}旋转值:${pointcloud.orientationUser}, 位置${math.toPrecision(pointcloud.translateUser.toArray(),3)}, 经纬度 ${locationLonLat}, spacing ${pointcloud.material.spacing}`, null, 17 )
-            
-            
-            //-------------------
-             
-            //viewer.mapView.showSources(false);  
-        }
-        
-        if(!Potree.settings.originDatasetId)Potree.settings.originDatasetId = data[0].id
-        var originDataset =  data.find(e=>e.id == Potree.settings.originDatasetId)  
-        
-        {//拿初始数据集作为基准。它的位置是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("WGS84", "+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs");
-             
-            let transform1 = proj4("WGS84", "NAVVIS:TMERC"); //这个ok  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;");
-            
-            
-            viewer.transform = {
-                lonlatToLocal : transform1,
-                lonlatTo4550 : transform2       // 转大地坐标EPSG:4550  
-            } 
-            
-            viewer.mapViewer && viewer.mapViewer.mapLayer.maps[0].updateProjection()
-            
-        }
-         
-        
-        data.forEach((dataset,index)=>{  
-            if(!ifReload){
-                var datasetCode = dataset.sceneCode || dataset.name //对应4dkk的场景码
-                var cloudPath = `${Potree.settings.urls.prefix1}/${Potree.settings.webSite}/${datasetCode}/data/${datasetCode}/webcloud/cloud.js` 
-                var timeStamp = dataset.createTime ? dataset.createTime.replace(/[^0-9]/ig,'') : '';  //每重算一次后缀随createTime更新一次 
-                //console.warn(dataset.name, 'timeStamp', timeStamp)
-                Potree.loadPointCloud(cloudPath, dataset.name ,datasetCode, timeStamp, e => {
-                    let scene = viewer.scene;
-                    let pointcloud = e.pointcloud; 
-                    let config = Potree.config.material
-                    let material = pointcloud.material; 
-                    
-                    pointcloud.hasDepthTex = Potree.settings.useDepthTex && (!!dataset.has_depth  ||  Potree.settings.isLocalhost && Potree.settings.number == 'SS-t-7DUfWAUZ3V') //test   
-                    material.minSize =  config.minSize
-                    material.maxSize =  config.maxSize   
-                    material.pointSizeType = config.pointSizeType //Potree.PointSizeType[config.pointSizeType]//Potree.PointSizeType.ADAPTIVE;//FIXED
-                    pointcloud.changePointSize(config.realPointSize)  //material.size =  config.pointSize;
-                    pointcloud.changePointOpacity(1)
-                    material.shape = Potree.PointShape.SQUARE; 
-                    pointcloud.color = pointcloud.material.color = dataset.color  
-                    pointcloud.dataset_id = dataset.id;//供漫游点找到属于的dataset点云
-                    pointcloud.timeStamp = timeStamp 
-                    transformPointcloud(pointcloud,dataset)
-                    scene.addPointCloud(pointcloud);
-                    
-                    if(!Potree.settings.isOfficial){ 
-                        Potree.settings.floorplanEnables[dataset.id] = true
-                        Potree.settings.floorplanType[dataset.id] = 'default'
-                    }
-                    
-                    
-                    pointcloudLoaded ++;
-                    if(pointcloudLoaded == datasetLength)pointcloudLoadDone()
-                    
-                    
-                
-                    Potree.loadPanos(dataset.id, (data) => { 
-                        //console.log('loadPanos',dataset.sceneCode, dataset.id, data)
-                        viewer.images360.addPanoData(data, dataset.id )
-                        panosLoaded ++; 
-                        if(panosLoaded == datasetLength){
-                            panosLoadDone() 
-                        } 
-                    })
-                })
-            }else{
-                let pointcloud = viewer.scene.pointclouds.find(p => p.dataset_id == dataset.id)
-                if(!pointcloud){
-                    Potree.Log('数据集id变了,自动使用第一个','#500')
-                    pointcloud = viewer.scene.pointclouds[0]
-                }
-                //先归零 
-                Alignment.translate(pointcloud,  pointcloud.translateUser.clone().negate())
-                Alignment.rotate(pointcloud, null,  - pointcloud.orientationUser)
-                
-                transformPointcloud(pointcloud, dataset)
-                 
-            } 
-                
-        })
-        
-        if(ifReload){ 
-            
-            //loadDone()
-        }
-        
-        
-    } 
-    
-    
-    
-    Potree.loadDatasets(Potree.loadDatasetsCallback) 
-     
-     
-
-    window.testTransform = function(locationLonLat, location1, location2){
-        proj4.defs("NAVVIS:test", "+proj=tmerc +ellps=WGS84 +lon_0=" + locationLonLat[0].toPrecision(15) + " +lat_0=" + locationLonLat[1].toPrecision(15));
-        
-        let transform = proj4("WGS84", "NAVVIS:test"); //这个ok  navvis里也是这两种转换 见proj4Factory
-        if(location1){//经纬度
-            return transform.forward(location1) 
-        }else{
-            return transform.inverse(location2) 
-        }            
-        
-    }       
-
-    window.THREE = THREE
-    window.buttonFunction = function(){
-        
-        
-         
-        viewer.scene.pointclouds.forEach(e=>e.predictNodeMaxLevel())
-               
-        
-        
-        /* 
-        viewer.startScreenshot({type:'measure', measurement:viewer.scene.measurements[0]}) 
-        
-        viewer.modules.RouteGuider.routeStart = new THREE.Vector3(0,0,-1.3)
-        viewer.modules.RouteGuider.routeEnd = new THREE.Vector3(-10,0,-1.3)
-       */
-        
-    }
-    
-    
-    if(Potree.settings.isLocalhost){
-        let before = {}
-        viewer.inputHandler.addEventListener('keydown',e=>{ //测试的代码
-            if(e.event.key == 't'){
-                viewer.images360.cube.visible = true
-                viewer.images360.cube.material.wireframe = true
-            }else if(e.event.key == 'y'){
-                viewer.images360.cube.material.wireframe = false
-                viewer.images360.cube.visible = Potree.settings.displayMode == 'showPanos'
-            }                
-        }) 
-        
-    }  
-    
-    
-}
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
-//=======================================================================
-/* 
-            漫游点编辑
- */
-//=======================================================================
-
-
-var panoEditStart = function(dom, number, fileServer){
-    Potree.settings.editType = 'pano'
-    Potree.settings.number = number 
-    
-    Potree.settings.unableNavigate = true
-    
-    
-    let viewer = new Potree.Viewer(dom); 
-    let Alignment = viewer.modules.Alignment
-	viewer.setEDLEnabled(false);
-    viewer.setFOV(config.view.fov); 
-    viewer.loadSettingsFromURL(); 
-    let datasetLoaded = 0;
-  
-    if(!Potree.settings.isOfficial){ 
-        viewer.loadGUI(() => {
-            viewer.setLanguage('en'); 
-            $("#menu_tools").next().show();
-            $("#panos").show();
-            $("#alignment").show(); 
-            viewer.toggleSidebar();
-        });
-        Potree.settings.sizeFitToLevel = true 
-    }
-    
-    var pointcloudLoadDone = function( ){//所有点云cloud.js加载完毕后 
-         
-        
-        
-        viewer.scene.pointclouds.forEach(c=>{
-            transformPointcloud(c)
-        })
-        viewer.images360.loadDone() 
-        viewer.scene.add360Images(viewer.images360); 
-        
-        viewer.updateModelBound()
-        let {boundSize, center} = viewer.bound
-       
-        Potree.Log(`中心点: ${math.toPrecision(center.toArray(),2)}, boundSize: ${math.toPrecision(boundSize.toArray(),2)} ` , null, 12)
-          
-        viewer.scene.view.setView({ 
-            position: center.clone().add(new THREE.Vector3(10,5,10)), 
-            target: center
-        })
-         
-        viewer.dispatchEvent({type:'loadPointCloudDone'})
-    
-        if(!Potree.settings.UserPointDensity){
-            Potree.settings.UserPointDensity = 'panoEdit'//'middle' 
-        }
-         
-        Potree.Log('loadPointCloudDone  点云加载完毕', null, 10)  
-        
-        viewer.dispatchEvent('allLoaded');
-    }
-    
-    
-    var transformPointcloud = (pointcloud )=>{ //初始化位置  
-        viewer.sidebar && viewer.sidebar.addAlignmentButton(pointcloud) 
-         
-        let orientation =  pointcloud.panos[0].dataRotation.z + Math.PI
-        
-        let location = pointcloud.panos[0].dataPosition.clone()//.negate()
-        
-        Alignment.rotate(pointcloud, null,  orientation  )   
-        Alignment.translate(pointcloud, location )  
-        
-        pointcloud.updateMatrixWorld()
-          
-    }   
-     
-     
-     
-         
-    
-    let loadPanosDone = Potree.loadPanosDone = (datasetId, panoData )=>{ //一个数据集获取到它的panos后
-        
-        Potree.settings.datasetsPanos[datasetId] = {panoData, panos:[]}
-         
-        console.log('panoData', datasetId, panoData)
-        
-        let panoCount = panoData.length
-        let pointcloudLoaded = 0
-        
-        let datasetsCount = Object.keys(Potree.settings.datasetsPanos).length
-       
-       
-        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 name = datasetId + '-'+pano.uuid
-            let timeStamp = 0
-            pano.index = index //注意:index不等于uuid,因为有的uuid缺失。但是visibles中存的是下标! 
-            
-            Potree.loadPointCloud(cloudPath, name , name, timeStamp, e => { //开始加载点云
-                let scene = viewer.scene;
-                let pointcloud = e.pointcloud; 
-                let config = Potree.config.material
-                let material = pointcloud.material; 
-                material.minSize =  config.minSize
-                material.maxSize =  config.maxSize   
-                material.pointSizeType = /* 'ADAPTIVE'// */config.pointSizeType //Potree.PointSizeType[config.pointSizeType]//Potree.PointSizeType.ADAPTIVE;//FIXED
-                pointcloud.changePointSize( 0.1 /* config.realPointSize  */   )  //material.size =  config.pointSize;
-                pointcloud.changePointOpacity(1)
-                material.shape = Potree.PointShape.SQUARE; 
-                pointcloud.color = config.pointColor  
-                pointcloud.dataset_id = datasetId;   //多个点云指向一个datasetId
-                pointcloud.panoUuid = pano.uuid
-                pointcloud.timeStamp = timeStamp
-                  
-                //transformPointcloud(pointcloud, pano)
-                scene.addPointCloud(pointcloud);
-                pointcloudLoaded ++;
-                 
-                if(pointcloudLoaded == panoCount ){
-                    datasetLoaded ++
-                    viewer.images360.addPanoData(panoData ,  datasetId )
-                    if(datasetLoaded == datasetsCount){
-                        pointcloudLoadDone()
-                    }
-                    
-                }
-                
-            })
-            
-        })
-        
-    }
-    
-    if(!Potree.settings.isOfficial){ 
-        Potree.settings.datasetsPano = {'testDataset':null}
-        Potree.loadPanosInfo( data=>{loadPanosDone('testDataset',  data.sweepLocations)} )  
-    
-    }
-    
-}
-
-
-
-  
-
-var mergeEditStart = function(dom){
-    Potree.settings.editType = 'merge' 
-    Potree.settings.intersectOnObjs = true
-    Potree.settings.boundAddObjs = true
-    Potree.settings.unableNavigate = true
-   
-    
-    
-    let viewer = new Potree.Viewer(dom );
-   
-    let Alignment = viewer.modules.Alignment
-     
-	viewer.setEDLEnabled(false);
-    viewer.setFOV(config.view.fov); 
-    viewer.loadSettingsFromURL(); 
-    { 
-        viewer.mainViewport.view.position.set(30,30,30) 
-        viewer.mainViewport.view.lookAt(0,0,0)
-        
-        viewer.updateModelBound()//init
-        //this.bound = new THREE.Box3(new THREE.Vector3(-1,-1,-1),new THREE.Vector3(1,1,1))
-        
-        viewer.transformationTool.setModeEnable('scale',false)
-        viewer.ssaaRenderPass.sampleLevel = 1 //  sampleLevel为1 的话,ground就不会变黑
-        
-        viewer.inputHandler.fixSelection = true //不通过点击屏幕而切换transfrom选中状态
-  
-    }
-    
-    Potree.settings.sizeFitToLevel = true//当type为衰减模式时自动根据level调节大小。每长一级,大小就除以2
-    Potree.loadPointCloudScene = function(sceneCode, type, id, done, onError){//对应4dkk的场景码
-          
-        let loadCloud = (cloudPath, sceneName, sceneCode, timeStamp, color)=>{
-            
-            Potree.loadPointCloud(cloudPath, sceneName , sceneCode, timeStamp, e => {
-                let scene = viewer.scene;
-                let pointcloud = e.pointcloud; 
-                let config = Potree.config.material
-                let material = pointcloud.material; 
-                
-                material.minSize =  config.minSize
-                material.maxSize =  config.maxSize   
-                material.pointSizeType = config.pointSizeType //Potree.PointSizeType[config.pointSizeType]//Potree.PointSizeType.ADAPTIVE;//FIXED
-                pointcloud.changePointSize(config.realPointSize)  //material.size =  config.pointSize;
-                pointcloud.changePointOpacity(1)
-                material.shape = Potree.PointShape.SQUARE; 
-                color && (pointcloud.color = pointcloud.material.color = color)     
-                pointcloud.timeStamp = timeStamp 
-                //transformPointcloud(pointcloud, originDataset)
-                scene.addPointCloud(pointcloud);
-                {
-                    
-                    viewer.updateModelBound()
-                    let {boundSize, center} = viewer.bound
-                    viewer.dispatchEvent({type:'loadPointCloudDone'})
-                    if(!Potree.settings.UserPointDensity){
-                        Potree.settings.UserPointDensity = 'high'//'middle' 
-                    }
-                     
-                    Potree.Log('loadPointCloudDone  点云加载完毕', null, 10)    
-                } 
-                    
-                /* Potree.loadPanos(dataset.id, (data) => { //暂时不加载panos了,因为没有id 
-                //console.log('loadPanos',dataset.sceneCode, dataset.id, data)
-                viewer.images360.addPanoData(data, dataset.id ) 
-                viewer.images360.loadDone() 
-                viewer.scene.add360Images(viewer.images360);    */   
-                viewer.dispatchEvent('allLoaded')
-                done(pointcloud)
-            },onError) 
-            
-            
-        }
-        
-        if(type == 'laser'){ 
-            Potree.loadDatasets((data)=>{
-                let originDataset = data.find(e=>e.sceneCode == sceneCode);//只加载初始数据集  
-                let timeStamp = originDataset.createTime ? originDataset.createTime.replace(/[^0-9]/ig,'') : '';  //每重算一次后缀随createTime更新一次 
-                let cloudPath = `${Potree.settings.urls.prefix1}/${Potree.settings.webSite}/${sceneCode}/data/${sceneCode}/webcloud/cloud.js` 
-                loadCloud(cloudPath, originDataset.sceneName, sceneCode, timeStamp, originDataset.color)
-            }, sceneCode, onError)
-        
-        }else{//las or ply
-            let name = type + '|' + id
-            let cloudPath = sceneCode + '/cloud.js' 
-            loadCloud(cloudPath, name, name, '' )
-        }   
-         
-    } 
-    
-    
-    
-    
-    
-    
-    
-    let setMatrix = (pointcloud)=>{//为了漫游点变换,要算一下 类似setMatrix
-                  
-        /* pointcloud.transformMatrix = new THREE.Matrix4().multiplyMatrices(pointcloud.matrix, pointcloud.pos1MatrixInvert)//还原一点位移
-        pointcloud.transformInvMatrix.copy(pointcloud.transformMatrix).invert()
-        
-        pointcloud.rotateMatrix = new THREE.Matrix4().makeRotationFromEuler(pointcloud.rotation);
-        pointcloud.rotateInvMatrix.copy(pointcloud.rotateMatrix).invert()
-        pointcloud.panos.forEach(e=>e.transformByPointcloud()) */
-        //pointcloud.updateBound()
-        //pointcloud.getPanosBound()  
-        viewer.updateModelBound()
-    } 
-
-    let moveModel = (e)=>{//根据鼠标移动的位置改变位置
-          
-        let camera = viewer.mainViewport.camera
-        var origin = new THREE.Vector3(e.pointer.x, e.pointer.y, -1).unproject(camera),
-        end = new THREE.Vector3(e.pointer.x, e.pointer.y, 1).unproject(camera)
-        var dir = end.sub(origin)
-        let planeZ = 0;
-        let r = (planeZ - origin.z)/dir.z
-        let x = r * dir.x + origin.x
-        let y = r * dir.y + origin.y
-        
-        //过后改为根据intersect的点来设置底部高度;这样的话,需要发送高度
-        
-        /*let pos = new THREE.Vector3(x,y,  planeZ  )
-         modelEditing.updateMatrixWorld()   
-        let boundCenter = modelEditing.boundingBox.getCenter(new THREE.Vector3).applyMatrix4(modelEditing.matrixWorld);
-         */
-        MergeEditor.moveBoundCenterTo(modelEditing,new THREE.Vector3(x,y, modelEditing.boundCenter.z))  //使模型中心的xy在鼠标所在位置
-         
-        modelEditing.dispatchEvent("position_changed") 
-         
-    }
-    let cancelMove = ()=>{ 
-        modelEditing = null
-        viewer.removeEventListener('global_mousemove', moveModel); 
-        viewer.removeEventListener('global_click', confirmPos); 
-    }
-    let confirmPos = ()=>{ 
-        MergeEditor.focusOn(modelEditing)
-        cancelMove()  
-        return {stopContinue:true}
-    }
-    
-     
-    
-    let modelType,  modelEditing, MergeEditor = viewer.modules.MergeEditor
-    Potree.addModel = function(prop, done, onProgress, onError){ //加载模型
-         
-    
-        let loadDone = (model)=>{ 
-            model.dataset_id = prop.id //唯一标识
-             
-            if(prop.position){
-                model.position.copy(prop.position)
-            }
-            if(prop.rotation){
-                model.rotation.setFromVector3(prop.rotation) 
-            }
-            if(prop.scale){
-                model.scale.set(prop.scale,prop.scale,prop.scale)
-            }
-              
-            if(model.isPointcloud){
-                model.renderOrder = Potree.config.renderOrders.model;  //same as glb
-            }
-            
-            
-            /* {//transform --------维持离地高度和中心点的版本
-                let updateBound = ()=>{ 
-                    model.updateMatrixWorld()
-                    viewer.updateModelBound() 
-                }  
-                let maintainBtmZAndCenter = ()=>{ 
-                    MergeEditor.maintainBoundXY(model)
-                    MergeEditor.setModelBtmHeight(model) 
-                    updateBound()
-                    model.dispatchEvent('transformChanged')  
-                }
-                model.addEventListener('position_changed', ()=>{
-                    updateBound()
-                    MergeEditor.getBoundCenter(model);//更新boundcenter
-                    MergeEditor.computeBtmHeight(model)
-                    if(prop.bottomRange && (model.btmHeight > prop.bottomRange.max || model.btmHeight < prop.bottomRange.min)){
-                        model.btmHeight = THREE.Math.clamp(model.btmHeight, prop.bottomRange.min, prop.bottomRange.max)
-                        MergeEditor.setModelBtmHeight(model)
-                        updateBound()
-                    }  
-                    model.dispatchEvent('transformChanged') 
-                })
-                model.addEventListener("rotation_changed", maintainBtmZAndCenter )
-                model.addEventListener("scale_changed", maintainBtmZAndCenter )
-                model.addEventListener('transformChanged', ()=>{
-                    MergeEditor.modelTransformCallback(model)
-                })
-                //离地高度只是boundingbox在transform后的最低点的高度,而非模型transform后的最低点的高度,所以旋转过后看起来不太准确
-            } */
-            
-            {//transform --------维持中心点的版本
-                let updateBound = ()=>{ 
-                    model.updateMatrixWorld()
-                    viewer.updateModelBound() 
-                }  
-                let maintainCenter = ()=>{ 
-                    //MergeEditor.maintainBoundXY(model) 
-                    MergeEditor.maintainBoundCenter(model) 
-                    updateBound()
-                    model.dispatchEvent('transformChanged')  
-                }
-                model.addEventListener('position_changed', ()=>{
-                    updateBound()
-                    MergeEditor.getBoundCenter(model);//更新boundcenter
-            
-                    model.dispatchEvent('transformChanged') 
-                })
-                model.addEventListener("rotation_changed", maintainCenter )
-                model.addEventListener("scale_changed", maintainCenter )
-                model.addEventListener('transformChanged', ()=>{
-                    MergeEditor.modelTransformCallback(model)
-                })
-            
-            } 
-            
-            model.updateMatrixWorld()
-            viewer.updateModelBound()
-            
-            MergeEditor.getBoundCenter(model) //初始化
-            model.lastMatrixWorld = model.matrixWorld.clone()
-            
-            done(model) // 先发送成功,因为2d界面会随机执行changePosition等初始化,然后这边再将模型移到中心地面上
-            
-            
-            if(prop.isFirstLoad){
-                
-                MergeEditor.moveBoundCenterTo(model, new THREE.Vector3(0,0,0))  
-                MergeEditor.setModelBtmHeight(model, 0) //初始加载设置离地高度为0
-                
-                if(prop.mode != 'single'){//如果不是模型展示页,模型会随着鼠标位置移动
-                    viewer.addEventListener('global_mousemove', moveModel); 
-                    viewer.addEventListener('global_click', confirmPos, 3);
-                    modelEditing = model;
-                }
-                model.dispatchEvent("position_changed") 
-            }else{
-                //MergeEditor.setModelBtmHeight(model, prop.bottom || 0) //默认离地高度为0
-                modelEditing = null
-            }
-            
-            
-            
-            
-        }
-        
-        
-        
-        
-        
-        
-        
-        if(prop.type == 'glb'){
-            
-            
-            
-            let callback = (object)=>{
-                //focusOnSelect(object, 1000)  
-                object.isModel = true
-                //object.dataset_id = Date.now() //暂时
-                
-                object.traverse(e=>e.material && (e.material.transparent = true))
-              
-                /* object.addEventListener('click',(e)=>{
-                    //只是为了能得到hoverElement识别才加这个侦听
-                }) */
-                 
-                loadDone(object)
-            }
-            
-             
-            let info = { 
-                name: prop.type, 
-                id: prop.id,
-                unlit:true,
-                /* transform : { 
-                    position : prop.position,
-                    rotation : new THREE.Euler().setFromVector3(prop.rotation), 
-                    scale: new THREE.Vector3(prop.scale,prop.scale,prop.scale),        
-                }  */               
-            }
-            
-            if(prop.type == 'glb'){
-                info.glburl = prop.url  
-            }
-                 
-              
-            viewer.loadModel(info , callback, onProgress, onError)
-            
-            
-            
-            
-            
-            
-            
-          }else{  
-            
-             //else if(prop.type == 'las' || prop.type == 'ply')
- 
-            Potree.loadPointCloudScene(prop.url, prop.type, prop.modelId, (pointcloud)=>{  
-                pointcloud.matrixAutoUpdate = true
-                pointcloud.initialPosition = pointcloud.position.clone()
-                
-                pointcloud.pos1MatrixInvert = new THREE.Matrix4().setPosition(pointcloud.initialPosition).invert()
-                
-                /* let maintainBtmZ = ()=>{
-                    MergeEditor.setModelBtmHeight(pointcloud)
-                    updateMatrix()
-                }
-                let updateMatrix = ()=>{ 
-                    setMatrix(pointcloud) 
-                    pointcloud.dispatchEvent('transformChanged')
-                }
-                pointcloud.addEventListener('position_changed', updateMatrix )  
-                pointcloud.addEventListener("orientation_changed", maintainBtmZ )
-                pointcloud.addEventListener("scale_changed", maintainBtmZ ) */
-                
-                loadDone(pointcloud)
-                /* pointcloud.addEventListener('select',(e)=>{
-                    if(Potree.settings.displayMode == 'showPanos')return
-                    console.log('select',e) 
-                    //viewer.setControls(viewer.orbitControls) 
-                    MergeEditor.focusOnSelect(pointcloud) 
-                    
-                    viewer.outlinePass.selectedObjects = [pointcloud]
-                    return {stopContinue:true}
-                },1)
-                pointcloud.addEventListener('deselect',(e)=>{
-                    console.log('deselect',e) 
-                    //viewer.setControls(viewer.fpControls)  
-                    viewer.outlinePass.selectedObjects = []
-                }) */
-                
-            }, onError)
-        
-             
-            
-            
-        }
-    }
-    return {THREE}
-}
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
-/* var changeLog = ()=>{ //如果移动端加了test反而出不来bug的话,用这个
-        
-    
-        var textarea = document.createElement('textarea');
-          textarea.id = "consoleLog";
-          
-          textarea.style.width = '160px';
-          textarea.style.height =  '200px'
-          textarea.style.position = 'fixed'
-          textarea.style.right = 0
-          textarea.style.bottom = '0'
-          textarea.style['z-index'] = 9999;
-          textarea.style.color = 'black';
-          textarea.style.opacity = 0.9;
-          textarea.style['font-size'] = '12px';
-          textarea.style['backgroundColor'] = '#ffffff'
-         
-          
-
-          document.getElementsByTagName("body")[0].appendChild(textarea);
-          var list = ["log", "error", "warn", "debug", "info", "time", "timeEnd"]
-          var exchange = function (o) {
-            console["old" + o] = console[o];
-            console[o] = function () {
-              var args =   Array.from(arguments)
-              console["old" + o].apply(this, arguments)
-              var t = document.getElementById("consoleLog").innerHTML;
-              
-              var str = ''
-              args.forEach(a=>{
-                  str += a + ' '
-              })
-              document.getElementById("consoleLog").innerHTML = str + "\n\n" + t;
-            }
-          }
-
-          for (var i = 0; i < list.length; i++) {
-            exchange(list[i])
-          } 
-   
-    
-    
-}
- 
-changeLog() */
- 
- 
- 
- 
- 
-export {start, panoEditStart, mergeEditStart}
-
-
-
-   /* 
-
-
-坐标转换问题:
-
-由于控制点可以随便输入,所以本地和地理位置的转换也是可拉伸的。而navvis的转换是等比由中心展开,
-所以对比两种转化方式时误差较大。
-
-另外地理注册控制点是有参考数据集的,若参考数据集和我放置在0,0,0的数据集一致,就可直接使用,否则要转换。
-
-
-
-   */

+ 0 - 301
src/utils/Common.js

@@ -1,301 +0,0 @@
-
-
-import * as THREE from "../../libs/three.js/build/three.module.js";
-
-
-var Common = {
-    sortByScore: function(list, request, rank){
-        var i = request ? Common.filterAll(list, request) : list
-        return 0 === i.length ? null : i = i.map(function(e) {
-            return {
-                item: e,
-                score: rank.reduce(function(t, i) {
-                    return t + i(e)
-                }, 0)
-            }
-        }).sort(function(e, t) {
-            return t.score - e.score;
-        })
-    } 
-    ,
-      
-    filterAll: function(e, t) {
-        return e.filter(function (e) {
-            return t.every(function (t) {
-                return t(e)
-            })
-        })
-    },
-    
-    
-    
-    //---------------
-    find : function(list, request, rank, sortByScore  ) { 
-        if(sortByScore){
-            var r = this.sortByScore(list, request, rank)
-            return  r && r[0] && r[0].item   
-        }else{
-            var i = request ? Common.filterAll(list, request) : list
-            return 0 === i.length ? null : (rank && rank.forEach(function(e) {
-                i = Common.stableSort(i, e)
-            }),
-            i[0])  
-        }
-        
-    }
-    
-    ,
-    stableSort: function(e, f) {//用到排序函数,涉及到两个item相减
-        return e.map(function(e, i) {
-            return {
-                value: e,
-                index: i
-            }
-        }).sort(function(e, u) { 
-            var n = f(e.value, u.value);
-            return 0 !== n ? n : e.index - u.index  //似乎就是加多了这一步:若差距为0,按照原顺序
-        }).map(function(e) {
-            return e.value
-        })
-    },
-    
-    average: function (e, t) {
-        if (0 === e.length)
-            return null;
-        for (var i = 0, n = 0, r = 0; r < e.length; r++) {
-            var o = t ? e[r][t] : e[r];
-            i += o,
-                n++
-        }
-        return i / n
-    },
-    
-    
-    //---------------------------
-    
-    
-    getMixedSet : function(arr1, arr2){//交集
-        return arr1.filter(item=>arr2.includes(item));
-    },
-    getUnionSet : function(arr1, arr2){//并集
-        return arr1.concat(arr2.filter(item=>!arr1.includes(item)))
-    },
-    getDifferenceSet : function(arr1, arr2){//差集  不能识别重复的,如getDifferenceSet([1,2,2],[1,1,2]) 为空
-        var arr11 = arr1.filter(item=>!arr2.includes(item));
-        var arr22 = arr2.filter(item=>!arr1.includes(item));
-        return arr11.concat(arr22)
-    },
-    getDifferenceSetMuti : function(arr){//收集绝对没有重复的元素,也就是判断出现次数=1的
-        var set = [];
-        arr.forEach(arr1=>{
-            arr1.forEach(item=>{
-                var index = set.indexOf(item)
-                if(index>-1){
-                    set.splice(index, 1)
-                }else{
-                    set.push(item)
-                }
-            })
-        })
-        return set;
-    }
-    ,
-    
-    
-    CloneJson : function(data){
-        var str = JSON.stringify(data)
-        return JSON.parse(str)
-    }
-    
-    ,
-     
-    CloneObject : function(copyObj, result, isSimpleCopy, simpleCopyList=[]) {
-        //isSimpleCopy 只复制最外层
-        //复制json		result的可能:普通数字或字符串、普通数组、复杂对象
-         
-        simpleCopyList.push(THREE.Object3D) //遇到simpleCopyList中的类直接使用不拷贝
-        
-        if(!copyObj || typeof copyObj == 'number' || typeof copyObj == 'string' || copyObj instanceof Function || simpleCopyList.some(className => copyObj instanceof className)){
-            return copyObj 
-        }
-        
-        result = result || {};
-        if (copyObj instanceof Array) {
-            return copyObj.map(e=>{ 
-                return this.CloneObject(e) 
-            }) 
-        }else{
-            if(copyObj.clone instanceof Function ){ //解决一部分
-                return copyObj.clone()
-            }
-        }
-        for (var key in copyObj) {
-            if (copyObj[key] instanceof Object && !isSimpleCopy)
-                result[key] = this.CloneObject(copyObj[key]);
-            else
-                result[key] = copyObj[key];
-            //如果是函数类同基本数据,即复制引用
-        }
-        return result;
-    }
-    ,
-    CloneClassObject :function(copyObj ){//复杂类对象
-        var newobj = new copyObj.constructor();
-        this.CopyClassObject(newobj, copyObj) 
-        
-        return newobj
-    }
-    
-    ,
-     
-    CopyClassObject :function(targetObj,  copyObj){//复杂类对象
-        for(let i in copyObj){
-            if(i in copyObj.__proto__)break; //到函数了跳出 
-              
-            targetObj[i] = this.CloneObject(copyObj[i], null )  
-            
-                
-            
-            /* else if(copyObj[i].clone instanceof Function ){
-                targetObj[i] = copyObj[i].clone()
-            }else{
-                targetObj[i] = copyObj[i];
-            } */ 
-        }
-    }
-    ,
-    
-    ifSame : function(object1, object2){
-        if(object1 == object2  )return true // 0 != undefined  , 0 == ''
-        else if(!object1 || !object2) return false
-        else if(object1.constructor != object2.constructor){
-            return false
-        }else if(object1 instanceof Array ) {
-            if(object1.length != object2.length)return false;
-            var _object2 = object2.slice(0);
-            
-            for(let i=0;i<object1.length;i++){ 
-                var u = _object2.find(e=>ifSame(object1[i], e));
-                if(u == void 0 && !_object2.includes(u) && !object1.includes(u))return false;
-                else{
-                    let index = _object2.indexOf(u);
-                    _object2.splice(index,1);
-                }
-            }
-            
-            return true
-        }else if(object1.equals instanceof Function ){//复杂数据仅支持这种,其他的可能卡住?
-            
-            return object1.equals(object2)
-              
-        }else if(typeof object1 == 'number' ||  typeof object1 == 'string'){
-            if(isNaN(object1) && isNaN(object2))return true
-            else return object1 == object2
-            
-        }else if(typeof object1 == "object"){
-            var keys1 = Object.keys(object1)
-            var keys2 = Object.keys(object2)
-            if(!ifSame(keys1,keys2))return false;
-            
-            for(let i in object1){
-                var same = ifSame(object1[i], object2[i]);
-                if(!same)return false
-            }
-            return true
-        }else{
-            console.log('isSame出现例外')
-        } 
-        
-    }
-    ,
-    replaceAll : function (str, f, e) {
-        //f全部替换成e
-        var reg = new RegExp(f, "g"); //创建正则RegExp对象  
-        return str.replace(reg, e);
-    } 
-    ,
-    downloadFile : function(data, filename, cb) {
-        var save_link = document.createElementNS('http://www.w3.org/1999/xhtml', 'a');
-        save_link.href = data;
-        save_link.download = filename;
-        var event = document.createEvent('MouseEvents');
-        event.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
-        save_link.dispatchEvent(event);
-        cb && cb();
-    }, 
-    
-    intervalTool:{  //延时update,防止卡顿
-        list:[],
-        
-        isWaiting:function(name, func, delayTime){
-            if(!this.list.includes(name)){  //如果没有该项, 则开始判断
-                var needWait = func(); //触发了改变,则等待一段时间后再自动判断
-                if(needWait){
-                    this.list.push(name);
-                    setTimeout(()=>{
-                        var a = this.list.indexOf(name);
-                        this.list.splice(a,1);
-                        this.isWaiting(name, func, delayTime) //循环
-                    },delayTime)
-                } 
-            }
-        },
-        /* wait:function(name, delayTime){
-            this.list.push(name);
-            setTimeout(()=>{
-                
-            },delayTime)
-        }, */
-    }
-    ,
-    pushToGroupAuto : function(items, groups, recognizeFunction){//自动分组。 items是将分到一起的组合。items.length = 1 or 2. 
-    
-        recognizeFunction = recognizeFunction || function(){}
-    
-        var atGroups = groups.filter(group=>group.find(
-            item => items[0] == item || recognizeFunction(item, items[0]) || items[1] == item || items[1] && recognizeFunction(item, items[1])
-        
-        )) 
-        if(atGroups.length){//在不同组
-            //因为items是一组的,所以先都放入组1
-            items.forEach(item=> {if(!atGroups[0].includes(item)) atGroups[0].push(item);})
-             
-            if(atGroups.length>1){//如果在不同组,说明这两个组需要合并 
-                var combineGroup = []
-                atGroups.forEach(group=>{
-                    combineGroup = Common.getUnionSet(combineGroup, group)
-                    groups.splice(groups.indexOf(group),1)
-                    
-                }) 
-                groups.push(combineGroup) 
-                
-            }
-        }else{//直接加入为一组
-           groups.push(items) 
-        }
-    },
-     
-    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 && 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
-    }
-    
-}  
-
-
-
-  
-export default Common 

+ 0 - 115
src/utils/CursorDeal.js

@@ -1,115 +0,0 @@
-
-import Common from './Common.js' 
-
-
-//处理cursor优先级
-
-
-var CursorDeal = {
-    priorityEvent : [//在前面的优先级高
-        {'zoomInCloud':'zoom-in'},
-        {'hoverPano':'pointer'}, 
-          
-        {'connectPano':`url({Potree.resourcePath}/images/connect.png),auto`},
-        {'disconnectPano':`url({Potree.resourcePath}/images/connect-dis.png),auto`},
-         
-        {'hoverLine':'pointer'},
-        
-        
-        
-        {"movePointcloud":'move'}, 
-        {"polygon_isIntersectSelf":'not-allowed'},
-        {"polygon_AtWrongPlace":'not-allowed'},
-        {"markerMove":'grab'},
-        {'mapClipMove':'move'},
-        {'mapClipRotate':`url({Potree.resourcePath}/images/rotate-cursor.png),auto`},
-        {'rotatePointcloud':`url({Potree.resourcePath}/images/rotate-cursor.png),auto`},
-        {'siteModelFloorDrag':'row-resize'},
-        {'addSth':'cell'},//or  crosshair
-         
-    ], 
-    list:[], //当前存在的cursor状态
-    currentCursorIndex:null,
-    
-    init : function(viewer, viewers){
-        
-        this.priorityEvent.forEach(e=>{//刚开始Potree.resourcePath没值,现在换
-            for(let i in e){
-                e[i] = Common.replaceAll(e[i],'{Potree.resourcePath}',Potree.resourcePath)
-            }
-        })
-        
-         
-        
-        this.domElements = viewers.map(e=>e.renderArea)  
-        
-        viewer.addEventListener("CursorChange",(e)=>{
-            if(e.action == 'add'){
-                this.add(e.name)
-            }else{
-                this.remove(e.name)
-            } 
-        })
-        
-        
-    },
-    
-    
-    add : function(name){
-        var priorityItem = this.priorityEvent.find(e=>e[name])
-        if(!priorityItem){
-            console.error('CursorDeal  未定义优先级 name:'+ name);
-            return
-        }
-        
-        
-        if(!this.list.includes(name)){
-            
-            this.judge({addItem: priorityItem, name})
-            
-            this.list.push(name)
-        }
-         
-    },
-    
-    
-    remove : function(name){
-        var index = this.list.indexOf(name);
-        if(index > -1){
-            this.list.splice(index, 1)
-            this.judge()
-        }
-        
-        
-        
-    },
-    
-    judge:function(o={}){
-        //console.log(o,this.list)
-        if(o.addItem){
-            var addIndex = this.priorityEvent.indexOf(o.addItem) 
-            if(addIndex < this.currentCursorIndex || this.currentCursorIndex == void 0){ 
-                this.domElements.forEach(e=>e.style.cursor = o.addItem[o.name] )
-                this.currentCursorIndex = addIndex
-            }  
-        }else{
-            var levelMax = {index:Infinity, cursor:null }
-            this.list.forEach(name=>{
-                var priorityItem = this.priorityEvent.find(e=>e[name])
-                var index = this.priorityEvent.indexOf(priorityItem)
-                if(index < levelMax.index){
-                    levelMax.index = index;
-                    levelMax.cursor = priorityItem[name]
-                }
-            })
-            this.currentCursorIndex = levelMax.index
-            this.domElements.forEach(e=>e.style.cursor = levelMax.cursor || '')
-        }
-        
-    }
-    
-     
-}
-
-
-export default CursorDeal;

+ 0 - 401
src/utils/DrawUtil.js

@@ -1,401 +0,0 @@
-
- 
-import * as THREE from "../../libs/three.js/build/three.module.js";
-import math from './math.js';
-import {Line2} from "../../libs/three.js/lines/Line2.js";
-import {LineGeometry} from "../../libs/three.js/lines/LineGeometry.js";
-import {LineMaterial} from "../../libs/three.js/lines/LineMaterial.js";
-//画线等函数--by 许钟文
-import {Features} from "../Features.js";
-
-var defaultColor = new THREE.Color(1,1,1);//config.applicationName == "zhiHouse" ? Colors.zhiBlue : Colors.lightGreen;
-
-var LineDraw = {
-    
-	createLine: function (posArr, o={}) {
-        //多段普通线  (第二个点和第三个点之间是没有线段的, 所以不用在意线段顺序)
-        var mat
-        if(o.mat){
-            mat = o.mat
-        }else{
-            let prop = {
-                lineWidth: o.lineWidth || 1,
-                //windows无效。 似乎mac/ios上粗细有效 ? 
-                color: o.color || defaultColor,
-                transparent: o.dontAlwaysSeen ? false : true,
-                depthTest: o.dontAlwaysSeen ? true : false, 
-            }
-            if(o.deshed ){
-                prop.dashSize = o.dashSize || 0.1,
-                prop.gapSize = o.gapSize || 0.1
-            }
-            mat = new THREE[o.deshed ? "LineDashedMaterial" : "LineBasicMaterial"](prop) 
-        }
-         
-        
-        
-        var line = new THREE.LineSegments(new THREE.BufferGeometry, mat);
-		line.renderOrder = o.renderOrder || 4
-  
-        this.moveLine(line, posArr)
-        
-		return line;  
-
-	},
-    
-    
-	moveLine: function (line, posArr) {
-        if(posArr.length == 0)return
-        let position = []
-        posArr.forEach(e=>position.push(e.x,e.y,e.z))
-        line.geometry.setAttribute('position', new THREE.Float32BufferAttribute(/* new Float32Array( */position/* ) */, 3));
-      
-		line.geometry.attributes.position.needsUpdate = true;
-		line.geometry.computeBoundingSphere();
-        if(line.material instanceof THREE.LineDashedMaterial){
-            line.computeLineDistances()
-            //line.geometry.attributes.lineDistance.needsUpdate = true;
-             
-            line.geometry.verticesNeedUpdate = true; //没用
-             
-        }
-	}  
-	,
-     
-	 
-	createFatLineMat : function(o){ 
-    
-        var supportExtDepth = !!Features.EXT_DEPTH.isSupported()  
-        
-        let params = $.extend({}, {
-            //默认
-            lineWidth : 5,  
-            color:0xffffff,
-            transparent : true, depthWrite:false,  depthTest:false,
-            dashSize : 0.1, gapSize:0.1, 
-        }, o, {
-            //修正覆盖:
-            dashed: o.dashWithDepth ? supportExtDepth && !!o.dashed : !!o.dashed ,
-            dashWithDepth:!!o.dashWithDepth,//只在被遮住的部分显示虚线
-            useDepth: !!o.useDepth,  
-            supportExtDepth,
-            
-        })
-        
-        
-        
-		var mat = new LineMaterial(params)
-         
-        
-        //if(o.dashed)(mat.defines.USE_DASH = "") 
-         
-		return 	mat;			
-	},
-    
-    /* 
-        创建可以改变粗细的线。 
-     */
-	createFatLine : function(posArr, o){  
-		var geometry = new LineGeometry(); 
-		geometry.setColors( o.color || [1,1,1]);
-
-		var matLine = o.material || this.createFatLineMat(o);
-		var line = new Line2( geometry, matLine );
-		//line.computeLineDistances();
-         
-		line.scale.set( 1, 1, 1 );
-		line.renderOrder = 2;
-        
-        this.moveFatLine(line, posArr)
-        
-		return line;
-
-	},
-    
-    
-    
-	moveFatLine: function(line, posArr){
-		var geometry = line.geometry;
-        var positions = [];
-         
-        posArr.forEach(e=>{positions.push(...e.toArray())})
-        
-        
-		if(positions.length > 0){
-            if(!geometry){
-                geometry = line.geometry = new LineGeometry(); 
-            }
-            if(geometry.attributes.instanceEnd && geometry.attributes.instanceEnd.data.array.length != positions.length){//positions个数改变会有部分显示不出来,所以重建
-                geometry.dispose();
-                geometry = new LineGeometry();
-                line.geometry = geometry
-            }
-            geometry.setPositions( positions ) 
-            
-            if(line.material.defines.USE_DASH != void 0){
-                //line.geometry.verticesNeedUpdate = true; //没用
-                line.geometry.computeBoundingSphere(); //for raycaster
-                line.computeLineDistances(); 
-            } 
-        }else{
-            geometry.dispose()
-            line.geometry = new LineGeometry(); 
-             
-        }
-        
-        
-	},
-    
-    updateLine: function(line, posArr){
-        if(line instanceof Line2){
-            LineDraw.moveFatLine(line,posArr) 
-        }else{
-            LineDraw.moveLine(line,posArr)
-        }  
-    },
-     /* 
-     
-        为line创建用于检测鼠标的透明mesh,实际是个1-2段圆台。
-        由于近大远小的原因,假设没有透视畸变、创建的是等粗的圆柱的话, 所看到的线上每个位置的粗细应该和距离成反比。所以将圆柱改为根据距离线性渐变其截面半径的圆台,在最近点(相机到线的垂足)最细。如果最近点在线段上,则分成两段圆台,否则一段。
-      */
-	createBoldLine:function(points, o){ 
-		o = o || {}
-		var cylinder = o && o.cylinder;  
-		var CD = points[1].clone().sub(points[0]);
-		
-		var rotate = function(){//根据端点旋转好模型
-			cylinder.lastVector = CD;//记录本次的端点向量 
-			var AB = new THREE.Vector3(0,-1,0) 
-			var axisVec = AB.clone().cross(CD).normalize(); //得到垂直于它们的向量,也就是旋转轴
-			var rotationAngle = AB.angleTo(CD);
-			cylinder.quaternion.setFromAxisAngle( axisVec, rotationAngle ) 
- 		} 
-		if(o && o.type == "init"){
-			cylinder = new THREE.Mesh()
-			cylinder.material = o.mat 
-			if(CD.length() == 0)return cylinder;
-			rotate()
-		}
-		
-		if(CD.length() == 0)return cylinder;
-		if(o.type != "update"){
-			var CDcenter = points[0].clone().add(points[1]).multiplyScalar(.5);
-			cylinder.position.copy(CDcenter);
-			
-			if(!cylinder.lastVector || o.type == "moveAndRotate")rotate()
- 			else if(cylinder.lastVector &&  CD.angleTo(cylinder.lastVector)>0) rotate()//线方向改了or线反向了 重新旋转一下模型
- 			if(config.isEdit && !objects.mainDesign.editing )return cylinder;//节省初始加载时间?
-		}
- 
-		
-		//为了保证线段任何地方的可检测点击范围看起来一样大,更新圆台的结构(但是在镜头边缘会比中心看起来大)
-		var height = points[0].distanceTo(points[1]);
-		var standPos = o && o.standPos || objects.player.position;
-		var k = config.isMobile ? 20 : 40;
-		var dis1 = points[0].distanceTo(standPos);
-		var dis2 = points[1].distanceTo(standPos); 
-	 
-		var foot = math.getFootPoint(standPos, points[0], points[1]);//垂足
-		
-        if(o.constantBold || objects.player.mode != "panorama"){
-            var width = 0.1//0.08;
-            var pts = [new THREE.Vector2(width ,height/2),new THREE.Vector2(width ,-height/2)]  
-        }else if(foot.clone().sub(points[0]).dot( foot.clone().sub(points[1])   ) > 0){//foot不在线段上
-			var pts = [new THREE.Vector2(dis1 / k,height/2),new THREE.Vector2(dis2 / k,-height/2)]
-		}else{//在线段上的话,要在垂足这加一个节点,因它距离站位最近,而两端较远
-			var dis3 = foot.distanceTo(standPos); 
-			var len = foot.distanceTo(points[0])
-			var pts = [new THREE.Vector2(dis1 / k,height/2),  new THREE.Vector2(dis3 / k,height/2-len),  new THREE.Vector2(dis2 / k,-height/2)]
-		} 
-		cylinder.geometry && cylinder.geometry.dispose();//若不删除会占用内存
- 		cylinder.geometry = new THREE.LatheBufferGeometry( pts, 4/* Math.min(dis1,dis2)<10?4:3 */ )  
-		cylinder.renderOrder = 2;
-		
-		return cylinder;
-	},  
-	updateBoldLine:function(cylinder, points, type, standPos, constantBold){  
-		this.createBoldLine(points,{type:type,  cylinder : cylinder, standPos:standPos, constantBold}) //type:move:平移 会改长短  , type:update根据距离和角度更新  不改长短
-	},	
-}
-
-var MeshDraw = { 
-    getShape:function(points, holes){
-        var shape = new THREE.Shape();
-        shape.moveTo( points[0].x, points[0].y );
-        for(var i=1,len=points.length; i<len; i++){
-            shape.lineTo(points[i].x, points[i].y ) 
-        } 
-        
-        /* var holePath = new THREE.Path()
-                .moveTo( 20, 10 )
-                .absarc( 10, 10, 10, 0, Math.PI * 2, true ) 
-            arcShape.holes.push( holePath );
-         */
-        if(holes){//挖空
-            holes.forEach((points)=>{
-                var holePath = new THREE.Path()
-                holePath.moveTo( points[0].x, points[0].y )
-                for(var i=1,len=points.length; i<len; i++){
-                    holePath.lineTo(points[i].x, points[i].y ) 
-                } 
-                shape.holes.push( holePath );
-            }) 
-        }
-        return shape        
-    },
-    getShapeGeo: function(points, holes){//获取任意形状(多边形或弧形)的形状面  //quadraticCurveTo() 这是弧形的含函数
-		
-		var geometry = new THREE.ShapeBufferGeometry( this.getShape(points, holes) );  //ShapeGeometry
-        
-       /*  var matrix = new THREE.Matrix4();//将竖直的面变为水平
-		matrix.set(//z = y 
-			1, 0, 0, 0,
-			0, 0, 0, 0,
-			0, 1, 0, 0,
-			0, 0, 0, 1 
-		)
-		geometry.applyMatrix(matrix) */
-		//geometry.computeVertexNormals();//对于光照需要的是点法线
-         
-		return geometry;
-		
-		
-	},
-    
-    
-    getExtrudeGeo:  function(points, holes, options={}){//获得挤出棱柱,可以选择传递height,或者extrudePath
-        var shape = this.getShape(points, holes) //points是横截面 [vector2,...]
-        
-        if(options.extrudePath ){// 路径 :[vector3,...]
-            
-            var length = extrudePath.reduce((total, currentValue, currentIndex, arr)=>{
-                if(currentIndex == 0)return 0
-                return total + currentValue.distanceTo(arr[currentIndex-1]);
-            },0)
-            options.extrudePath = new THREE.CatmullRomCurve3(extrudePath, options.closed ,  'catmullrom'  /* 'centripetal' */  , options.tension)
-            
-           
-        }
-         
-        var extrudeSettings = $.extend(options,{
-            steps: options.steps != void 0 ? options.steps : ( options.extrudePath ? Math.round(length/0.3) : 1),
-            bevelEnabled: false, //不加的话,height为0时会有圆弧高度
-            //depth
-        }) 
-        var geometry = new THREE.ExtrudeBufferGeometry( shape, extrudeSettings );
-        return geometry;
-    },
-    
-    
-	getUnPosPlaneGeo : function(){//获取还没有赋值位置的plane geometry
-		var e = new Uint16Array([0, 1, 2, 0, 2, 3])
-		//	, t = new Float32Array([-.5, -.5, 0, .5, -.5, 0, .5, .5, 0, -.5, .5, 0])
-			, i = new Float32Array([0, 0, 1, 0, 1, 1, 0, 1])
-			, g = new THREE.BufferGeometry;
-		g.setIndex(new THREE.BufferAttribute(e, 1)),
-		//g.addAttribute("position", new n.BufferAttribute(t, 3)),
-		g.setAttribute("uv", new THREE.BufferAttribute(i, 2)) 
-		return function(){
-			return g
-		}	 
-	}(), 
-	getPlaneGeo : function(A,B,C,D){
-		var geo = this.getUnPosPlaneGeo().clone();
-		var pos = [
-			A.x, A.y, A.z, 
-			B.x, B.y, B.z, 
-			C.x, C.y, C.z, 
-			D.x, D.y, D.z  
-		] 
-		//geo.addAttribute("position", new THREE.BufferAttribute(pos, 3)) 
-        geo.setAttribute('position', new THREE.Float32BufferAttribute(pos, 3));
-      
-        
-		geo.computeVertexNormals()
-		geo.computeBoundingSphere() //for raycaster
-		return geo;
-	}, 
-	drawPlane : function(A,B,C,D, material){   
-		var wall = new THREE.Mesh(this.getPlaneGeo(A,B,C,D), material); 
-		return wall;
-	  
-	}, 
-	movePlane: function(mesh, A,B,C,D){
-		var pos = new Float32Array([
-			A.x, A.y, A.z, 
-			B.x, B.y, B.z, 
-			C.x, C.y, C.z, 
-			D.x, D.y, D.z  
-		])
-		mesh.geometry.addAttribute("position", new THREE.BufferAttribute(pos, 3)) 
-		mesh.geometry.computeBoundingSphere()//for checkIntersect
-	}  
-    
-    ,
-    
-    createGeometry:function(posArr, faceArr, uvArr, normalArr ){//创建复杂mesh.  faceArr:[[0,1,2],[0,2,3]]
-        let geo = new THREE.BufferGeometry;
-        
-        let positions = []; 
-        posArr.forEach(p=>positions.push(p.x,p.y,p.z)); 
-        geo.setAttribute('position', new THREE.Float32BufferAttribute(positions, 3));
-        
-        if(faceArr){
-            let indice = []
-            faceArr.forEach(f=>indice.push(...f));
-            geo.setIndex(indice) // auto set Uint16BufferAttribute or Uint32BufferAttribute
-        }
-        
-        if(uvArr){
-            let uvs = []
-            uvArr.forEach(uv=>uvs.push(uv.x,uv.y));
-            geo.setAttribute("uv", new THREE.Float32BufferAttribute(uvs, 2)) 
-        } 
-        
-        if(normalArr){
-            let normals = []
-            normalArr.forEach(n=>normals.push(n.x,n.y,n.z));
-            geo.setAttribute("normal", new THREE.Float32BufferAttribute(normals, 3)) 
-        }
-        /*  
-        geo.computeVertexNormals()
-		geo.computeBoundingSphere() //for raycaster 
-          */
-        return geo
-    },
-    
-    
-    updateGeometry:function(geo, posArr, faceArr, uvArr, normalArr ){//创建复杂mesh.  faceArr:[[0,1,2],[0,2,3]]
-        
-        let positions = []; 
-        posArr.forEach(p=>positions.push(p.x,p.y,p.z)); 
-        geo.setAttribute('position', new THREE.Float32BufferAttribute(positions, 3));
-        geo.attributes.position.needsUpdate = true;
-		 
-        if(faceArr){
-            let indice = []
-            faceArr.forEach(f=>indice.push(...f));
-            geo.setIndex(indice) // auto set Uint16BufferAttribute or Uint32BufferAttribute
-        }
-        
-        if(uvArr){
-            let uvs = []
-            uvArr.forEach(uv=>uvs.push(uv.x,uv.y));
-            geo.setAttribute("uv", new THREE.Float32BufferAttribute(uvs, 2)) 
-        } 
-        
-        if(normalArr){
-            let normals = []
-            normalArr.forEach(n=>normals.push(n.x,n.y,n.z));
-            geo.setAttribute("normal", new THREE.Float32BufferAttribute(normals, 3)) 
-        }
-        /*  
-        geo.computeVertexNormals()
-		
-          */
-        geo.computeBoundingSphere() //for raycaster and visi
-        return geo
-    }
-} 
-
-export {LineDraw, MeshDraw} ;

+ 0 - 47
src/utils/History.js

@@ -1,47 +0,0 @@
-
-import {ExtendEventDispatcher} from "../custom/ExtendEventDispatcher.js";
-
-
-class History extends ExtendEventDispatcher{
-    
-    constructor(o){ 
-        super()
-        
-        this.list = []
-        
-        this.callback = o.callback
-    }
-    
-    undo(){
-        let last = this.list.pop();
-        last && this.callback && this.callback(last) 
-        
-        
-    }
-    
-    
-    redo(){//暂时不写
-        
-        
-        
-    }
-    
-    writeIn(item){
-        
-        this.list.push(item)
-        
-    }
-    
-    
-    clear(){
-        
-        this.list.length = 0
-        
-    }
-    
-    
-    
-}
-
-
-export default History

+ 0 - 315
src/utils/MathLight.js

@@ -1,315 +0,0 @@
-var MathLight = {};
-MathLight.RADIANS_PER_DEGREE = Math.PI / 180;
-MathLight.DEGREES_PER_RADIAN = 180 / Math.PI;
-MathLight.Vector3 = function(e, t, i) {
-    this.x = e || 0,
-    this.y = t || 0,
-    this.z = i || 0
-};
-
-MathLight.Matrix4 = function() {
-    this.elements = new Float32Array([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]),
-    arguments.length > 0 && console.error("MathLight.Matrix4: the constructor no longer reads arguments. use .set() instead.")
-};
-
-MathLight.Matrix4.prototype = {
-    identity: function() {
-        return this.set(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1),
-        this
-    },
-    copy: function(e) {
-        return this.elements.set(e.elements),
-        this
-    },
-    applyToVector3: function(e) {
-        var t = e.x
-            , i = e.y
-            , n = e.z
-            , r = this.elements;
-        return e.x = r[0] * t + r[4] * i + r[8] * n + r[12],
-        e.y = r[1] * t + r[5] * i + r[9] * n + r[13],
-        e.z = r[2] * t + r[6] * i + r[10] * n + r[14],
-        this
-    },
-    getInverse: function(e, t) {
-        var i = this.elements
-            , n = e.elements
-            , r = n[0]
-            , o = n[1]
-            , a = n[2]
-            , s = n[3]
-            , l = n[4]
-            , c = n[5]
-            , h = n[6]
-            , u = n[7]
-            , d = n[8]
-            , p = n[9]
-            , f = n[10]
-            , g = n[11]
-            , m = n[12]
-            , v = n[13]
-            , A = n[14]
-            , y = n[15]
-            , C = p * A * u - v * f * u + v * h * g - c * A * g - p * h * y + c * f * y
-            , I = m * f * u - d * A * u - m * h * g + l * A * g + d * h * y - l * f * y
-            , E = d * v * u - m * p * u + m * c * g - l * v * g - d * c * y + l * p * y
-            , b = m * p * h - d * v * h - m * c * f + l * v * f + d * c * A - l * p * A
-            , w = r * C + o * I + a * E + s * b;
-        if (0 === w) {
-            var _ = "MathLight.Matrix4.getInverse(): can't invert matrix, determinant is 0";
-            if (t)
-                throw new Error(_);
-            return console.warn(_),
-            this.identity()
-        }
-        var T = 1 / w;
-        return i[0] = C * T,
-        i[1] = (v * f * s - p * A * s - v * a * g + o * A * g + p * a * y - o * f * y) * T,
-        i[2] = (c * A * s - v * h * s + v * a * u - o * A * u - c * a * y + o * h * y) * T,
-        i[3] = (p * h * s - c * f * s - p * a * u + o * f * u + c * a * g - o * h * g) * T,
-        i[4] = I * T,
-        i[5] = (d * A * s - m * f * s + m * a * g - r * A * g - d * a * y + r * f * y) * T,
-        i[6] = (m * h * s - l * A * s - m * a * u + r * A * u + l * a * y - r * h * y) * T,
-        i[7] = (l * f * s - d * h * s + d * a * u - r * f * u - l * a * g + r * h * g) * T,
-        i[8] = E * T,
-        i[9] = (m * p * s - d * v * s - m * o * g + r * v * g + d * o * y - r * p * y) * T,
-        i[10] = (l * v * s - m * c * s + m * o * u - r * v * u - l * o * y + r * c * y) * T,
-        i[11] = (d * c * s - l * p * s - d * o * u + r * p * u + l * o * g - r * c * g) * T,
-        i[12] = b * T,
-        i[13] = (d * v * a - m * p * a + m * o * f - r * v * f - d * o * A + r * p * A) * T,
-        i[14] = (m * c * a - l * v * a - m * o * h + r * v * h + l * o * A - r * c * A) * T,
-        i[15] = (l * p * a - d * c * a + d * o * h - r * p * h - l * o * f + r * c * f) * T,
-        this
-    },
-    makeRotationFromQuaternion: function(e) {
-        var t = this.elements
-            , i = e.x
-            , n = e.y
-            , r = e.z
-            , o = e.w
-            , a = i + i
-            , s = n + n
-            , l = r + r
-            , c = i * a
-            , h = i * s
-            , u = i * l
-            , d = n * s
-            , p = n * l
-            , f = r * l
-            , g = o * a
-            , m = o * s
-            , v = o * l;
-        return t[0] = 1 - (d + f),
-        t[4] = h - v,
-        t[8] = u + m,
-        t[1] = h + v,
-        t[5] = 1 - (c + f),
-        t[9] = p - g,
-        t[2] = u - m,
-        t[6] = p + g,
-        t[10] = 1 - (c + d),
-        t[3] = 0,
-        t[7] = 0,
-        t[11] = 0,
-        t[12] = 0,
-        t[13] = 0,
-        t[14] = 0,
-        t[15] = 1,
-        this
-    }
-};
-
-MathLight.Quaternion = function(e, t, i, n) {
-    this._x = e || 0,
-    this._y = t || 0,
-    this._z = i || 0,
-    this._w = void 0 !== n ? n : 1
-};
-
-MathLight.Quaternion.prototype = {
-    get x() {
-        return this._x
-    },
-    set x(e) {
-        this._x = e
-    },
-    get y() {
-        return this._y
-    },
-    set y(e) {
-        this._y = e
-    },
-    get z() {
-        return this._z
-    },
-    set z(e) {
-        this._z = e
-    },
-    get w() {
-        return this._w
-    },
-    set w(e) {
-        this._w = e
-    },
-    copy: function(e) {
-        this._x = e.x,
-        this._y = e.y,
-        this._z = e.z,
-        this._w = e.w
-    },
-    inverse: function() {
-        return this.conjugate().normalize()
-    },
-    conjugate: function() {
-        return this._x *= -1,
-        this._y *= -1,
-        this._z *= -1,
-        this
-    },
-    length: function() {
-        return Math.sqrt(this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w)
-    },
-    normalize: function() {
-        var e = this.length();
-        return 0 === e ? (this._x = 0,
-        this._y = 0,
-        this._z = 0,
-        this._w = 1) : (e = 1 / e,
-        this._x = this._x * e,
-        this._y = this._y * e,
-        this._z = this._z * e,
-        this._w = this._w * e),
-        this
-    },
-    setFromAxisAngle: function(e, t) {
-        var i = t / 2
-            , n = Math.sin(i);
-        return this._x = e.x * n,
-        this._y = e.y * n,
-        this._z = e.z * n,
-        this._w = Math.cos(i),
-        this
-    },
-    setFromUnitVectors: function() {
-        var e, t, i = 1e-6;
-        return function(n, o) {
-            return void 0 === e && (e = new MathLight.Vector3),
-            t = MathLight.dot(n, o) + 1,
-            t < i ? (t = 0,
-            Math.abs(n.x) > Math.abs(n.z) ? MathLight.setVector(e, -n.y, n.x, 0) : MathLight.setVector(e, 0, -n.z, n.y)) : MathLight.cross(n, o, e),
-            this._x = e.x,
-            this._y = e.y,
-            this._z = e.z,
-            this._w = t,
-            this.normalize()
-        }
-    }(),
-    multiply: function(e) {
-        return this.multiplyQuaternions(this, e)
-    },
-    premultiply: function(e) {
-        return this.multiplyQuaternions(e, this)
-    },
-    multiplyQuaternions: function(e, t) {
-        var i = e._x
-            , n = e._y
-            , r = e._z
-            , o = e._w
-            , a = t._x
-            , s = t._y
-            , l = t._z
-            , c = t._w;
-        return this._x = i * c + o * a + n * l - r * s,
-        this._y = n * c + o * s + r * a - i * l,
-        this._z = r * c + o * l + i * s - n * a,
-        this._w = o * c - i * a - n * s - r * l,
-        this
-    }
-};
-
-MathLight.convertWorkshopVector = function(e) {
-    return new MathLight.Vector3(-e.x,e.y,e.z)
-};
-
-MathLight.convertWorkshopQuaternion = function(e) {
-    return new MathLight.Quaternion(-e.x,e.y,e.z,-e.w).multiply(new MathLight.Quaternion(Math.sqrt(2) / 2,Math.sqrt(2) / 2,0,0))
-};
-
-MathLight.convertWorkshopOrthoZoom = function(e) {
-	//return e === -1 ? -1 : e / 16 * ($('#player').width() / $('#player').height()) / n.workshopApsect
-	return e === -1 ? -1 : e  * ($("#player").width() / $("#player").height())  ;
-};
-
-MathLight.convertWorkshopPanoramaQuaternion = function(e) {
-    return new MathLight.Quaternion(e.x,-e.y,-e.z,e.w).normalize().multiply((new MathLight.Quaternion).setFromAxisAngle(new MathLight.Vector3(0,1,0), 270 * MathLight.RADIANS_PER_DEGREE))
-};
-
-MathLight.normalize = function(e) {
-    var t = e.x * e.x + e.y * e.y + e.z * e.z
-        , i = Math.sqrt(t);
-    e.x /= i,
-    e.y /= i,
-    e.z /= i
-};
-
-MathLight.dot = function(e, t) {
-    return e.x * t.x + e.y * t.y + e.z * t.z
-};
-
-MathLight.cross = function(e, t, i) {
-    var n = e.x
-        , r = e.y
-        , o = e.z;
-    i.x = r * t.z - o * t.y,
-    i.y = o * t.x - n * t.z,
-    i.z = n * t.y - r * t.x
-};
-
-MathLight.setVector = function(e, t, i, n) {
-    e.x = t,
-    e.y = i,
-    e.z = n
-};
-
-MathLight.copyVector = function(e, t) {
-    t.x = e.x,
-    t.y = e.y,
-    t.z = e.z
-};
-
-MathLight.addVector = function(e, t) {
-    e.x += t.x,
-    e.y += t.y,
-    e.z += t.z
-};
-
-MathLight.subVector = function(e, t) {
-    e.x -= t.x,
-    e.y -= t.y,
-    e.z -= t.z
-};
-
-MathLight.applyQuaternionToVector = function(e, t) {
-    var i = t.x
-        , n = t.y
-        , r = t.z
-        , o = e.x
-        , a = e.y
-        , s = e.z
-        , l = e.w
-        , c = l * i + a * r - s * n
-        , h = l * n + s * i - o * r
-        , u = l * r + o * n - a * i
-        , d = -o * i - a * n - s * r;
-    t.x = c * l + d * -o + h * -s - u * -a,
-    t.y = h * l + d * -a + u * -o - c * -s,
-    t.z = u * l + d * -s + c * -a - h * -o
-};
-
-MathLight.angleBetweenVectors = function(e, t) {
-    return Math.acos(MathLight.dot(e, t))
-};
-
-
-
-export default MathLight

+ 0 - 192
src/utils/SplitScreen.js

@@ -1,192 +0,0 @@
-import {View} from "../viewer/View.js";
-import Viewport from "../viewer/Viewport.js";
-import * as THREE from "../../libs/three.js/build/three.module.js";
-import {ExtendEventDispatcher} from "../custom/ExtendEventDispatcher.js";
-
- 
-
-class SplitScreen extends ExtendEventDispatcher{
-    constructor (args = {}) {
-		super();
-        
-    }
-    
-    
-    splitStart(cameraProps){ 
-        let viewports = []
-      
-        let subViewports = [viewer.mainViewport]
-        if(viewer.mapViewer){
-            subViewports.push(viewer.mapViewer.viewports[0])
-        }
-        
-        let length = cameraProps.length
-        for(let i=0;i<length;i++){
-            let prop = cameraProps[i];
-            let viewport;
-            let v = subViewports.find(e=>e.name == (prop.name2||prop.name)) 
-            if(v){
-                viewport = v
-                viewport.left = prop.left; viewport.bottom = prop.bottom; viewport.width = prop.width; viewport.height = prop.height;
-            }
-            
-            if(!viewport){
-                let view = new View()  
-                if(prop.limitBound)view.limitBound = prop.limitBound
-                prop.direction && (view.direction = prop.direction)
-                
-                viewport = new Viewport(view , this.getOrthoCamera(), prop )
-                if(prop.viewContainsPoints)viewport.viewContainsPoints = prop.viewContainsPoints
-                
-                //viewport.unableDepth = true //depthBasicMaterial等在此viewport中不开启depth 
-                
-            }    
-            if(viewport.camera.type == 'OrthographicCamera'  ){
-                viewport.targetPlane = new THREE.Plane()
-                viewport.shiftTarget = new THREE.Vector3 //project在targetPlane上的位置
-            }
-            viewport.fitMargin = prop.margin
-            viewports.push(viewport) 
-        } 
-        viewer.viewports = viewports;
-        viewer.updateScreenSize({forceUpdateSize:true})
-        viewports.forEach(viewport=>{
-            if(viewport.name == 'MainView')return
-            this.viewportFitBound(viewport, viewer.bound.boundingBox , viewer.bound.center , 0, viewport.fitMargin)
-        }) 
-        return viewports
-    } 
-    
-    
-    unSplit(){
-        this.unfocusViewport()
-        viewer.viewports = [viewer.mainViewport] 
-        viewer.mainViewport.width = 1;
-        viewer.mainViewport.height = 1;
-        viewer.mainViewport.left = 0
-        viewer.mainViewport.bottom = 0;   
-        viewer.updateScreenSize({forceUpdateSize:true})        
-    }
-    
-    viewportFitBound(viewport,  bound,  center, duration=0, margin){
-        let view = viewport.view
-        let info = {bound} 
-        let {boundSize, boundCenter} = this.getViewBound(viewport)
-        
-        
-        
-        viewport.targetPlane.setFromNormalAndCoplanarPoint( view.direction.clone(), boundCenter )  
-        viewport.targetPlane.projectPoint(center, viewport.shiftTarget)  //target转换到过模型中心的平面,以保证镜头一定在模型外 this.shiftTarget是得到的
-        
-        info.endPosition = this.getPosOutOfModel(viewport, boundSize) 
-        
-        //if(viewport.name == 'mapViewport')info.endPosition.z = Math.max(Potree.config.map.cameraHeight, info.endPosition.z) 
-         
-        info.margin = margin || {x:30, y:30}    
-        view.moveOrthoCamera(viewport, info ,  duration   )
-    } 
-    
-    
-    getViewBound(viewport){
-        let {boundSize, center} = viewer.bound
-        if(viewport.viewContainsPoints){//视野范围内必须要包含的点,直接算入模型区域。这时候得到的boundCenter和模型中心不重合
-            let boundingBox = viewer.bound.boundingBox.clone()
-            viewport.viewContainsPoints.forEach(point=>{
-                boundingBox.expandByPoint(point)
-            })
-            boundSize = boundingBox.getSize(new THREE.Vector3)
-            center = boundingBox.getCenter(new THREE.Vector3)
-        }
-         
-        return {boundSize, boundCenter:center }  
-    }
-    
-    getPosOutOfModel(viewport, boundSize){ 
-        //let {boundSize, center} = viewer.bound
-        boundSize = boundSize || this.getViewBound(viewport).boundSize
-        let expand = 10; 
-        let radius = boundSize.length() //    / 2  
-        let position = viewport.shiftTarget.clone().sub(viewport.view.direction.clone().multiplyScalar(radius + expand))  
-         
-        return position 
-    } 
-    
-    updateCameraOutOfModel(){//因为移动模型导致模型超出相机外,所以更新位置
-        viewer.viewports.forEach((viewport, i )=>{
-            if(viewport != viewer.mainViewport){
-                let {boundSize, boundCenter} = this.getViewBound(viewport)
-                viewport.targetPlane.setFromNormalAndCoplanarPoint( viewport.view.direction.clone(), boundCenter) 
-                viewport.targetPlane.projectPoint(viewport.view.position, viewport.shiftTarget)  //target转换到过模型中心的平面,以保证镜头一定在模型外 this.shiftTarget是得到的
-         
-                 let endPosition = this.getPosOutOfModel(viewport, boundSize) 
-                 //if(viewport.name == 'mapViewport')endPosition.z = Math.max(Potree.config.map.cameraHeight, endPosition.z) 
-                 viewport.view.position.copy(endPosition)
-            } 
-        })  
-    }  
-     
-    rotateSideCamera(viewport, angle){//侧视图绕模型中心水平旋转
-         
-        //let {boundSize, center} = viewer.bound
-        let {boundSize, boundCenter } = this.getViewBound(viewport)  
-        let center = this.focusCenter || boundCenter //旋转中心,一般是所有模型的中心,除非想指定中心点
-        
-        //找到平移向量
-        viewport.targetPlane.setFromNormalAndCoplanarPoint(viewport.view.direction  , center ) 
-        viewport.targetPlane.projectPoint(viewport.view.position,  viewport.shiftTarget )  //target转换到过模型中心的平面,以保证镜头一定在模型外
-        let vec = new THREE.Vector3().subVectors(center, viewport.shiftTarget)//相对于中心的偏移值,旋转后偏移值也旋转
-        
-        //旋转
-        var rotMatrix = new THREE.Matrix4().makeRotationAxis(new THREE.Vector3(0,0,1), angle) 
-        
-        viewport.view.direction = viewport.view.direction.applyMatrix4(rotMatrix)
-         
-         
-        vec.applyMatrix4(rotMatrix)
-        viewport.shiftTarget.subVectors(center,vec) //新的
-        
-        
-        viewport.view.position = this.getPosOutOfModel(viewport, boundSize)
-        
-    }
-    
-    getOrthoCamera(){
-        return new THREE.OrthographicCamera(-100, 100, 100, 100, 0.01, 10000)
-    } 
-    
-    focusOnViewport(name){//全屏
-        viewer.viewports.forEach((viewport, i )=>{
-            if(viewport.name == name){
-                this.focusInfo = {
-                    name,
-                    left : viewport.left, bottom : viewport.bottom, height : viewport.height, width : viewport.width
-                }
-                viewport.left = 0;  viewport.bottom = 0;   viewport.height = 1;  viewport.width = 1  
-                
-            }else{
-                viewport.active = false
-            }
-        })
-         
-        viewer.updateScreenSize({forceUpdateSize:true}) 
-    } 
-    
-    unfocusViewport(){
-        if(!this.focusInfo)return
-        viewer.viewports.forEach((viewport, i )=>{ 
-            if(this.focusInfo.name == viewport.name){//全屏的恢复 
-                viewport.left = this.focusInfo.left;
-                viewport.bottom = this.focusInfo.bottom;
-                viewport.height = this.focusInfo.height;
-                viewport.width = this.focusInfo.width;
-            }
-            viewport.active = true 
-        }) 
-        viewer.updateScreenSize({forceUpdateSize:true}) 
-        this.focusInfo = null
-    } 
-    
-}
-
-export default SplitScreen
-

+ 0 - 342
src/utils/SplitScreen4Views.js

@@ -1,342 +0,0 @@
- 
-import * as THREE from "../../libs/three.js/build/three.module.js";
-
-import SplitScreen from "./SplitScreen.js";
-
-
-const viewportProps = [
-    {
-        left:0.5,
-        bottom:0.5,
-        width: 0.5,height:0.5,
-        name : 'MainView',   
-        //view: viewer.scene.view,
-        active: true,
-    },
-    {
-        left:0,
-        bottom:0.5,
-        width: 0.5,height:0.5,
-        name : 'top',   
-        name2 : 'mapViewport', 
-        axis:["x","y"],
-        direction : new THREE.Vector3(0,0,-1), //镜头朝向
-        //axisSign:[1,1],
-        active: true,
-        //相机位置在z轴正向
-    },
-    {
-        left:0.5,
-        bottom:0,
-        width: 0.5,height:0.5,
-        name : 'right', 
-        axis:["y","z"],
-        direction : new THREE.Vector3(1,0,0),
-        //axisSign:[1,1],
-        active: true,
-        //相机位置在x轴负向  右下角屏
-    },
-    {
-        left:0,
-        bottom:0,
-        width: 0.5,height:0.5, 
-        name : 'back', 
-        axis:["x","z"],
-        direction : new THREE.Vector3(0,-1,0),
-        //axisSign:[-1,1],    // 从镜头方向看  x向左 所以取负 
-        active: true,
-        //相机位置在y轴正向  左下角屏
-    },
-]
-
-
-
-
-var SplitScreen4Views = new SplitScreen()
-
-  
-
- 
-SplitScreen4Views.split = function(o={}){
-    var defaultCamera = viewer.scene.getActiveCamera()
-   
-    let {boundSize, center} = viewer.bound
-        
-    viewer.setLimitFar(false) 
-    viewer.mapViewer.attachToMainViewer(true,'split4Screens','dontSet') 
-    
-    let viewports = this.splitStart(viewportProps)
-    
-    //覆盖在map上、点云等其他物体之下的一层背景
-    let mapViewport = viewer.mapViewer.viewports[0]   
-    mapViewport.noPointcloud = false
-    //隐藏地图游标
-    //viewer.updateVisible(viewer.mapViewer.cursor, 'split4Screens', false)
-    /* viewer.images360.panos.forEach(pano=>{
-        viewer.updateVisible(pano.mapMarker, 'split4Screens', false) //希望这时候mapMarker已经建好了吧
-    }) */
-        
-        
-        
-        
-    //材质 
-    this.statesBefore = { 
-        pointDensity : Potree.settings.pointDensity,
-        displayMode : Potree.settings.displayMode,
-        
-        position: viewer.images360.position,
-        target: viewer.scene.view.getPivot(),
-         
-        
-        //---
-        //ifShowMarker : Potree.settings.ifShowMarker, 
-    }
-    
-    viewer.setPointStandardMat(true,null,true) //切换到标准模式(主要为了mainViewport)  点云使用标准大小 
-    
-    var matBefore = { 
-        opacity : new Map() 
-    } 
-    var newOpacityMap = new Map() 
-     
-    viewer.scene.pointclouds.forEach(e=>{
-        matBefore.opacity.set(e, e.temp.pointOpacity) 
-        matBefore.colorType = e.material.activeAttributeName
-        
-        /* { 
-            var map = new Map()
-            newOpacityMap.set(e, map )
-            var size = e.bound.getSize()
-            viewports.forEach(viewport=>{//根据bound设置opacity,越小的要靠越近,需要大的opacity。但似乎影响太大了
-                if(viewport.name == 'MainView')return;
-                var prop = viewportProps.find(v => viewport.name == v.name2||viewport.name == v.name)
-                let axis = prop.axis
-                var width = size[axis[0]]
-                var height = size[axis[1]]
-                var area = width * height
-                map.set(viewport, 5000/area);
-            })
-            
-        }  */ 
-    }) 
-    
-    let beforeRender = function(){
-        viewer.scene.pointclouds.forEach(e=>{ 
-            if(this.name == "MainView"){ 
-                e.material.activeAttributeName = matBefore.colorType // 'rgba'
-                
-                e.material.useFilterByNormal = false 
-                e.changePointOpacity(matBefore.opacity.get(e)) //1 //恢复下 e.temp.pointOpacity 其实就是1
-                
-                Potree.settings.pointDensity = 'fourViewportsMain'/* 'fourViewports' */ //本来想比另外三屏高一点质量,结果发现会闪烁,因为点云加载需要时间 (navvis仿版也是一样,以后看看能否优化)
-                
-            }else{ 
-                e.material.activeAttributeName = "color"
-                e.material.useFilterByNormal = true 
-                
-                Potree.settings.pointDensity = 'fourViewports' //强制降低点云质量
-                
-                e.changePointOpacity(0.6/* newOpacityMap.get(e).get(viewport), true */);  //多数据集有的数据集很小,放大后显示特别淡
-                //console.log(e.name, viewport.name, e.temp.pointOpacity, e.material.opacity)
-            }                 
-        })  
-    }    
-    viewports.forEach(viewport=>{viewport.beforeRender = beforeRender})
-     
-     
-     
-    this.enableMap(false)
-    this.enableFloorplan(false)
-    viewer.mapViewer.setViewLimit('expand') //多数据集距离远时可以任意远,所以不限制了。但是这样就会看到地图边界了怎么办?
-    //viewer.dispatchEvent({'type': 'beginSplitView' }) 
-    //viewer.updateScreenSize({forceUpdateSize:true})   
-    
-    
-      
-    //this.viewportFitBound(mapViewport, boundSize, center)
-    //Potree.settings.ifShowMarker = false
-    Potree.settings.displayMode = 'showPointCloud'
-} 
-
-
- 
-  
-
-
-SplitScreen4Views.recover = function(){
-    this.unSplit()
-    
-    /* const {width, height} = viewer.renderer.getSize(new THREE.Vector2());
-    viewer.renderer.setViewport(0,0,width,height)
-    viewer.renderer.setScissorTest( false ); */
-    
-    viewer.setView({
-        position: this.statesBefore.position,
-        target: this.statesBefore.target,
-        duration:300,
-        callback:function(){ 
-        }
-    })
-    
-    
-    
-    viewer.mainViewport.beforeRender = null 
-    viewer.setLimitFar(true)
-    
-    let mapViewport = viewer.mapViewer.viewports[0]
-    viewer.mapViewer.attachToMainViewer(false) 
-    //viewer.updateVisible(viewer.mapViewer.cursor, 'split4Screens', true)
-    /* viewer.images360.panos.forEach(pano=>{
-        viewer.updateVisible(pano.mapMarker, 'split4Screens', true)
-    }) */
-    mapViewport.noPointcloud = true
-    { 
-        this.enableMap(Potree.settings.mapEnable)
-        this.enableFloorplan(Potree.settings.floorplanEnable)
-        if(this.floorplanListener){
-            viewer.mapViewer.mapLayer.removeEventListener( 'floorplanLoaded', this.floorplanListener )  
-            this.floorplanListener = null  
-        } 
-    }
-     
-    Potree.settings.pointDensity = this.statesBefore.pointDensity
-    if(!Potree.settings.isOfficial){
-        Potree.settings.displayMode = this.statesBefore.displayMode
-    }
-    
-    viewer.scene.pointclouds.forEach(e=>{ 
-        //e.material.color.set(this.statesBefore.mat.color)
-        //e.material.activeAttributeName = this.statesBefore.mat.colorType 
-        e.material.useFilterByNormal = false
-        //e.material.opacity = this.statesBefore.mat.opacity  
-    }) 
-    viewer.setPointStandardMat(false)
-    viewer.mapViewer.setViewLimit('standard')
-    
-    //Potree.settings.ifShowMarker = this.statesBefore.ifShowMarker
-    //viewer.dispatchEvent({'type': 'finishSplitView' }) 
-    //viewer.updateScreenSize({forceUpdateSize:true})  
-    
-} 
-
- 
-
-
-SplitScreen4Views.updateMapViewerBG = function(){
-    let mapViewport = viewer.mapViewer.viewports[0]
-    if(this.floorplanEnabled || this.mapEnabled){
-        mapViewport.background = 'overlayColor'
-        mapViewport.backgroundColor = new THREE.Color(0,0,0)
-        mapViewport.backgroundOpacity = 0.5; 
-    }else{
-        mapViewport.background = null
-        mapViewport.backgroundColor = null
-        mapViewport.backgroundOpacity = null
-    }
-}
-
-SplitScreen4Views.setFloorplanDisplay = function(e, show=false){ 
-    //viewer.updateVisible(e.floorplan.objectGroup, 'splitScreen', !!show)  
-    //e.floorplan.objectGroup.visible = !!show  
-    //viewer.mapViewer.mapLayer.needUpdate = true
-    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)
-    
-    
-    //viewer.mapViewer.mapGradientBG = viewer.background == 'gradient' && !enable
-    this.mapEnabled = enable
-    this.updateMapViewerBG()
-   
-    
-    
-},
-//直接覆盖原设置
-
-SplitScreen4Views.enableFloorplan = function(enable){ //是否让自定义的平面图显示
-    let floorplans = viewer.mapViewer.mapLayer.maps.filter(e=>e.name.includes('floorplan'))
-    
-    if(this.floorplanListener){
-        viewer.mapViewer.mapLayer.removeEventListener( 'floorplanLoaded', this.floorplanListener )  
-    }
-    this.floorplanListener = (e)=>{
-        this.setFloorplanDisplay(e, enable) 
-    }
-    
-    viewer.mapViewer.mapLayer.addEventListener( 'floorplanLoaded', this.floorplanListener ) //万一之后才加载 
-    
-    
-    if(!enable){ 
-        //隐藏平面图 
-        floorplans.forEach(floorplan=>this.setFloorplanDisplay({floorplan},false))  
-         
-    }else{
-         
-        floorplans.forEach(floorplan=>this.setFloorplanDisplay({floorplan},true))  
-        
-    }
-    
-    
-    if (enable && floorplans.length == 0) Potree.loadMapEntity('all',true)
-    
-    this.floorplanEnabled = enable
-    this.updateMapViewerBG()
-},
-
-/* viewportFitBound:function(viewport, boundSize, center){  //使一个viewport聚焦在某个范围
-    var prop = viewportProps.find(v => viewport.name == v.name2||viewport.name == v.name)
-    let axis = prop.axis 
-    let expand = 10;
-    let position = center.clone()
-    var moveAtAxis = ['x','y','z'].find(e=>!(axis.includes(e))) 
-    
-    if(viewport.name == 'mapViewport'){ 
-        let ori = viewport.view.position[moveAtAxis] 
-        position[moveAtAxis] = ori //不改变这个值,尤其是mapViewer中的z
-    }else{
-        position[moveAtAxis] += boundSize[moveAtAxis]/2+expand//移动到bounding边缘外
-    }
-    
-    viewport.view.position.copy(position)
-    
-    var width = Math.max(boundSize[axis[0]],  boundSize[axis[1]] * viewport.camera.aspect)//视口宽度(米)
-    var margin = 50 //px
-    viewport.camera.zoom = (viewport.resolution.x - margin) / width  
-    viewport.camera.updateProjectionMatrix()
-},
- */
- 
-SplitScreen4Views.focusOnPointCloud = function(pointcloud){//三个屏都聚焦在这个点云 
-    var boundSize = pointcloud.bound.getSize(new THREE.Vector3);
-    var center = pointcloud.bound.getCenter(new THREE.Vector3); 
-    let target = pointcloud.panosBound && pointcloud.panosBound.center  //看向pano集中的地方,也就是真正有点云的地方。(因为需要展示所有点云,所以没办法用这个做为center)
-    this.focusOnObject(pointcloud.bound, center,target)
-    
-    viewer.flyToDataset({pointcloud, dontMoveMap:true, duration:0})
-}
-
-SplitScreen4Views.focusOnObject = function(bound, center, target, duration=0){
-    viewer.viewports.forEach(e=>{
-        if(e.name == 'MainView'){
-            /* let len = boundSize.length()
-            let distance = THREE.Math.clamp(e.view.position.distanceTo(center),  len * 0.01,  len*0.3 ) //距离限制
-            //viewer.focusOnObject({position:center}, 'point', duration, {distance, direction: e.view.direction,dontMoveMap:true} )//平移镜头
-            //为了方便定位,直接飞到中心位置:
-            e.view.setView({
-                position:center,  duration,  target   
-            }) */  
-        }else{
-            this.viewportFitBound(e, bound, center)
-        }
-    })
-} 
-    
- 
-export default SplitScreen4Views

+ 0 - 393
src/utils/UnitConvert.js

@@ -1,393 +0,0 @@
- 
-const FEET_TO_INCHES_FACTOR = 12
-const EIGHTHS_SYMBOLS = ["", "⅛", "¼", "⅜", "½", "⅝", "¾", "⅞"]//eighths 八分之……
-
-
-class UnitOfMeasurement{//转化单位工具
-    constructor(t, e, n, i){
-        this.name = t,
-        this.symbol = e,
-        this.base = n,
-        this.factor = i 
-    }
-    toBase(t) {//换算到base
-        return t * this.factor
-    }
-   
-    fromBase(t) {//换算到当前
-        return t / this.factor
-    }
-}
-
-    
-    
-    
-
-/*  var o = function t(e) {
-    this.gettext = e,
-    t.METRIC = this.gettext("metric", void 0, "measurement system"),
-    t.IMPERIAL = this.gettext("imperial", void 0, "measurement system") 
-    
-    
-};
-e.UoMSystem = o;
-
-let UoMSystem = {
-    
-} */
-
-
-
-/* var MeasurementDomain = {
-
-    DISTANCE : "DISTANCE",
-    t.AREA = "AREA",
-    t.VOLUME = "VOLUME",
-    t.DATA = "DATA",
-    t
-}
- 
-
- */
-    
-    
-    
-    
-    
-     
-    
-var UnitsOfMeasurement = {
- 
-    MILLIMETER : ["Millimeter", "mm"],
-    CENTIMETER : ["Centimeter", "cm"],
-    METER : ["Meter", "m"],
-    KILOMETER : ["Kilometer", "km"],
-    INCH : ["Inch", "in"],
-    FOOT : ["Foot", "ft"],
-    MILE : ["Mile", "mi"],
-    SQUAREMETER : ["SquareMeter", "m²"],
-    SQUAREFOOT : ["SquareFoot", "ft²"],
-    CUBICMETER : ["CubicMeter", "m³"],
-    CUBICFOOT : ["CubicFoot", "ft³"],
-    BYTE : ["Byte", "B"],
-    KILOBYTE : ["Kilobyte", "kB"],
-    MEGABYTE : ["Megabyte", "MB"],
-    GIGABYTE : ["Gigabyte", "GB"],
-    TERABYTE : ["Terabyte", "TB"],
-    PETABYTE : ["Petabyte", "PB"],
-    
-    
-    init : function() {
-        var e, n, i, a, s, c, l, u, d, p, h, 
-        f = new UnitOfMeasurement(UnitsOfMeasurement.METER[0],UnitsOfMeasurement.METER[1],void 0,1), 
-        g = new UnitOfMeasurement(UnitsOfMeasurement.SQUAREMETER[0],UnitsOfMeasurement.SQUAREMETER[1],void 0,1), 
-        m = new UnitOfMeasurement(UnitsOfMeasurement.CUBICMETER[0],UnitsOfMeasurement.CUBICMETER[1],void 0,1), 
-        v = new UnitOfMeasurement(UnitsOfMeasurement.BYTE[0],UnitsOfMeasurement.BYTE[1],void 0,1);
-        
-        UnitsOfMeasurement.DISTANCE = (
-            (e = {})['metric'] = ((n = {})[UnitsOfMeasurement.MILLIMETER[0]] = new UnitOfMeasurement(UnitsOfMeasurement.MILLIMETER[0],UnitsOfMeasurement.MILLIMETER[1],f,.001),
-            n[UnitsOfMeasurement.CENTIMETER[0]] = new UnitOfMeasurement(UnitsOfMeasurement.CENTIMETER[0],UnitsOfMeasurement.CENTIMETER[1],f,.01),
-            n[UnitsOfMeasurement.METER[0]] = f,
-            n[UnitsOfMeasurement.KILOMETER[0]] = new UnitOfMeasurement(UnitsOfMeasurement.KILOMETER[0],UnitsOfMeasurement.KILOMETER[1],f,1e3),
-            n),
-            e['imperial'] = ((i = {})[UnitsOfMeasurement.INCH[0]] = new UnitOfMeasurement(UnitsOfMeasurement.INCH[0],UnitsOfMeasurement.INCH[1],f,.0254),
-            i[UnitsOfMeasurement.FOOT[0]] = new UnitOfMeasurement(UnitsOfMeasurement.FOOT[0],UnitsOfMeasurement.FOOT[1],f,.3048),
-            i[UnitsOfMeasurement.MILE[0]] = new UnitOfMeasurement(UnitsOfMeasurement.MILE[0],UnitsOfMeasurement.MILE[1],f,1609.344),
-            i),
-            e);
-            
-        UnitsOfMeasurement.AREA = ((a = {})['metric'] = ((s = {})[UnitsOfMeasurement.SQUAREMETER[0]] = g,
-            s),
-            a['imperial'] = ((c = {})[UnitsOfMeasurement.SQUAREFOOT[0]] = new UnitOfMeasurement(UnitsOfMeasurement.SQUAREFOOT[0],UnitsOfMeasurement.SQUAREFOOT[1],g,.092903),
-            c),
-            a);
-            
-        
-        UnitsOfMeasurement.VOLUME = ((l = {})['metric'] = ((u = {})[UnitsOfMeasurement.CUBICMETER[0]] = m,
-            u),
-            l['imperial'] = ((d = {})[UnitsOfMeasurement.CUBICFOOT[0]] = new UnitOfMeasurement(UnitsOfMeasurement.CUBICFOOT[0],UnitsOfMeasurement.CUBICFOOT[1],m,.0283168),
-            d),
-            l);
-        
-        //数据大小
-        var y = ((p = {})[UnitsOfMeasurement.BYTE[0]] = v,
-            p[UnitsOfMeasurement.KILOBYTE[0]] = new UnitOfMeasurement(UnitsOfMeasurement.KILOBYTE[0],UnitsOfMeasurement.KILOBYTE[1],v,1e3),
-            p[UnitsOfMeasurement.MEGABYTE[0]] = new UnitOfMeasurement(UnitsOfMeasurement.MEGABYTE[0],UnitsOfMeasurement.MEGABYTE[1],v,1e6),
-            p[UnitsOfMeasurement.GIGABYTE[0]] = new UnitOfMeasurement(UnitsOfMeasurement.GIGABYTE[0],UnitsOfMeasurement.GIGABYTE[1],v,1e9),
-            p[UnitsOfMeasurement.TERABYTE[0]] = new UnitOfMeasurement(UnitsOfMeasurement.TERABYTE[0],UnitsOfMeasurement.TERABYTE[1],v,1e12),
-            p[UnitsOfMeasurement.PETABYTE[0]] = new UnitOfMeasurement(UnitsOfMeasurement.PETABYTE[0],UnitsOfMeasurement.PETABYTE[1],v,1e15),
-            p);
-            UnitsOfMeasurement.DATA = ((h = {})['metric'] = y,
-            h['imperial'] = y,
-            h)
-    }
-    ,
-    getUnitsOfMeasurementByDomain : function(e) {
-        
-        return this[e.toUpperCase()]
-        
-        /* switch (e.toUpperCase()) {
-        case a.DISTANCE:
-            return t.DISTANCE;
-        case a.AREA:
-            return t.AREA;
-        case a.VOLUME:
-            return t.VOLUME;
-        case a.DATA:
-            return t.DATA;
-        default:
-            console.error(e + " measurement domain is not supported.")
-        } */
-    }
-    ,
-    getUnitsOfMeasurementByDomainAndSystem : function(domain, system) {
-        var r = this.getUnitsOfMeasurementByDomain(domain);
-        if (r.hasOwnProperty(system.toLowerCase()))
-            return r[system.toLowerCase()];
-        console.error(n + " measurement system is not supported.")
-    }
-    ,
-    getDefaultUnitByDomainAndSystem : function(e, n) {
-        switch (e.toUpperCase()) {
-            case 'DISTANCE':
-                switch (n.toLowerCase()) {
-                case 'metric':
-                    return this.DISTANCE['metric'][this.METER[0]];
-                case 'imperial':
-                    return this.DISTANCE['imperial'][this.FOOT[0]];
-                default:
-                    console.error(n + " measurement system is not supported.")
-                }
-            case 'AREA':
-                switch (n.toLowerCase()) {
-                case 'metric':
-                    return this.AREA['metric'][this.SQUAREMETER[0]];
-                case 'imperial':
-                    return this.AREA['imperial'][this.SQUAREFOOT[0]];
-                default:
-                    console.error(n + " measurement system is not supported.")
-                }
-            case 'VOLUME':
-                switch (n.toLowerCase()) {
-                case 'metric':
-                    return this.VOLUME['metric'][this.CUBICMETER[0]];
-                case 'imperial':
-                    return this.VOLUME['imperial'][this.CUBICFOOT[0]];
-                default:
-                    console.error(n + " measurement system is not supported.")
-                }
-            case 'DATA':
-                switch (n.toLowerCase()) {
-                case 'metric':
-                    return this.DATA['metric'][this.BYTE[0]];
-                case 'imperial':
-                    return this.DATA['imperial'][this.BYTE[0]];
-                default:
-                    console.error(n + " measurement system is not supported.")
-                }
-            default:
-                console.error(e + " measurement domain is not supported.")
-        }
-    }
-    
-   
-}
-    
-    
-    
-
- 
-
-
-
-
-
-class UnitService{
-    
-    constructor(/* e, n, i */){
-          //this.LanguageService = e,
-        //this.localStorageService = n,
-        //this.gettext = i,
-        //this.unitChanged = new r.Signal,
-        this.LOCAL_STORAGE_KEY = "iv_unit_key"//?
-        UnitsOfMeasurement.init()
-        this.unitSystems = ['metric', 'imperial']//[o.UoMSystem.METRIC, o.UoMSystem.IMPERIAL],
-        this.defaultSystem = 'metric'//'imperial'
-        //var a = this.LanguageService.getBrowserLocaleString().toLowerCase();
-        //this.defaultSystem =  t.isLocaleImperial(a) ? o.UoMSystem.IMPERIAL : o.UoMSystem.METRIC,
-        
-        //this.initUnit()
-        
-    }
-     
-    
-    /* initUnit() {
-        var t = this.localStorageService.get(this.LOCAL_STORAGE_KEY);
-        if (t)
-            for (var e = 0, n = this.unitSystems; e < n.length; e++) {
-                var i = n[e];
-                if (i === t)
-                    return void this.setUnit(i, !0)
-            }
-        this.setUnit(this.defaultSystem, !1)
-    }
-    setUnit(t, e) {
-        this.currentSystem !== t && (this.currentSystem = t,
-        this.unitChanged.emit()),
-        e && this.localStorageService.set(this.LOCAL_STORAGE_KEY, t)
-    } */
-    
-   
-    
-    /*isLocaleImperial(e) {
-        return t.IMPERIAL_LOCALES.indexOf(e.toLowerCase()) >= 0
-    }
-    ,
-     t.IMPERIAL_LOCALES = ["en_us"],
-    t.ɵfac(e) {
-        return new (e || t)(c.ɵɵinject(l.LanguageService),
-        c.ɵɵinject("localStorageService"),c.ɵɵinject("gettext"))
-    }
-     ,
-    t.ɵprov = c.ɵɵdefineInjectable({
-        token: t,
-        factory: t.ɵfac,
-        providedIn: "root"
-    }), */
-    
-} 
-
-
-
-    
-
-class UoMService{
-    constructor(/* UnitService */){
-        this.UnitService = new UnitService()/* UnitService */
-        
-    }
-    scopedConvert (t, n, precision = 2, r, minFactor) {
-        return  this.convert(t, n, precision, r, minFactor)
-    }
-    
-    convert(number, domain, precision = 2, system, minFactor, ifEighths = !1) { 
-        if (!number) return "";
-        var s = this.getMostRelevantMeasurement(domain, system || this.UnitService.currentSystem, number, minFactor);
-        return this.getFormattedMeasurementString(s[0], s[1], precision, ifEighths)
-    }
-    
-    convertBack(number, domain, precision = 2, fromSystem, minFactor ) { //从英制转到'metric'
-        if (!number) return "";
-        var d = UnitsOfMeasurement.getDefaultUnitByDomainAndSystem(domain,'metric')
-        
-        var s = this.getMostRelevantMeasurement2(domain, fromSystem, number, minFactor);
-        return this.getFormattedMeasurementString(s[0], d, precision ) 
-        
-        
-        /* 栗子:
-        viewer.unitConvert.convertBack(1, 'area', 5, 'imperial')
-        '0.09290 m²'
-        viewer.unitConvert.convertBack(1, 'Distance', 2, 'imperial')
-        '0.03 m' 
-        */
-    }
-    
-    getFormattedMeasurementString(number, unit, precision, ifEighths) {
-        var result 
-        if(ifEighths && unit.name === UnitsOfMeasurement.FOOT[0]){
-            result = this.formatImperialDistance(number * FEET_TO_INCHES_FACTOR)
-        }else if(ifEighths && unit.name === UnitsOfMeasurement.INCH[0]){
-            result = this.formatImperialDistance(number)
-             
-        }else{
-            result = number.toLocaleString(void 0, {
-                minimumFractionDigits: precision,
-                maximumFractionDigits: precision
-            }) + " " + unit.symbol
-        }
-        
-        return result
-    }
-    
-    formatImperialDistance(e) {
-        var n = Math.round(8 * e)
-          , i = Math.floor(n / 8)
-          , r = Math.floor(i / FEET_TO_INCHES_FACTOR)
-          , o = i - r * FEET_TO_INCHES_FACTOR
-          , a = EIGHTHS_SYMBOLS[n % 8]
-          , s = 0 === o && "" !== a ? "" : o;
-          
-        "" !== s && "" !== a && (a = " " + a)   
-        
-        return  0 !== r ? r + "' " + s + a + '"' : "" + s + a + '"'
-    }
-    
-    getMostRelevantMeasurement(domain, system, number, minFactor=0) {
-        /* var a = r.values(UnitsOfMeasurement.getUnitsOfMeasurementByDomainAndSystem(domain, system))
-          , s = r.filter(a, function(t) {  
-            return t.factor >= i
-        })
-          , c = r.reduce(s, function(t, e) {
-            return e.fromBase(number) < t.fromBase(number) && e.fromBase(number) >= 1 ? e : t
-        }); */
-        let a = []
-        let u = UnitsOfMeasurement.getUnitsOfMeasurementByDomainAndSystem(domain, system)
-        for(let i in u){a.push(u[i])}
-         
-        let s = a.filter(m=>m.factor >= minFactor) 
-         
-        
-       
-        let c = s.reduce(function(prev, currentValue) {//reduce最终值是最后一次return的值 ( 没看懂这句话作用) 
-            return currentValue.fromBase(number) < prev.fromBase(number) && currentValue.fromBase(number) >= 1 ? currentValue : prev
-        })
-        
-        return c ? [c.fromBase(number), c] : void 0
-    }
-    
-    getMostRelevantMeasurement2(domain, system, number, minFactor=0) {//add
-        let a = []
-        let u = UnitsOfMeasurement.getUnitsOfMeasurementByDomainAndSystem(domain, system)
-        for(let i in u){a.push(u[i])} 
-        let s = a.filter(m=>m.factor >= minFactor)  
-        let c = s.reduce(function(prev, currentValue) {//reduce最终值是最后一次return的值 ( 没看懂这句话作用) 
-            return currentValue.toBase(number) < prev.toBase(number) && currentValue.toBase(number) >= 1 ? currentValue : prev
-        }) 
-        return c ? [c.toBase(number), c] : void 0
-    }
-    /* ɵfac(e){
-        return new (e || t)(c.ɵɵinject(l.UnitService))
-    }
-    
-    ɵprov = c.ɵɵdefineInjectable({
-        token: t,
-        factory: t.ɵfac,
-        providedIn: "root"
-    }) */
-   
-}
-
-
-/* 
-使用方法:
-
-
-初始化:
-    var unitConvert = new UoMService();
- 
-    要设置的类型,两种:var unitSystem = 'metric' || 'imperial'  
- 
-
-使用:
-
-    面积:
-        let text = viewer.unitConvert.convert(area, 'area', void 0,  unitSystem,  )  
-
-    长度:
-        var text = viewer.unitConvert.convert(distance, 'distance', void 0, unitSystem, 0.1 , true)//distance要传0.1这个factor。 最后一个参数传true代表使用八分之一表示。
-
- */
-
-
-
-export {UoMService}

File diff suppressed because it is too large
+ 0 - 367
src/utils/browser.js


+ 0 - 19
src/utils/cameraLight.js

@@ -1,19 +0,0 @@
-import MathLight from './MathLight.js'
-
-var cameraLight = {
-    clampVFOV: function(currentFov, maxHFov, width, height) {//限制currentFov, 使之造成的横向fov不大于指定值maxHFov
-        var r = cameraLight.getHFOVFromVFOV(currentFov, width, height);
-        return r > maxHFov ? cameraLight.getVFOVFromHFOV(maxHFov, width, height) : currentFov
-    },
-    getHFOVForCamera: function(camera,  getRad) {
-        return cameraLight.getHFOVByScreenPrecent(camera.fov, camera.aspect, getRad)
-    }, 
-    //add
-    getHFOVByScreenPrecent: function(fov, percent, getRad) { //当fov为占比百分百时,percent代表在屏幕上从中心到边缘的占比
-        let rad = 2 * Math.atan(percent * Math.tan(fov * MathLight.RADIANS_PER_DEGREE / 2));
-        if(getRad)return rad 
-        else return rad * MathLight.DEGREES_PER_RADIAN;
-    }
-};
-
-export default cameraLight

+ 0 - 608
src/utils/math.js

@@ -1,608 +0,0 @@
-
-import * as THREE from "../../libs/three.js/build/three.module.js";
-import searchRings from "./searchRings.js";
-
-
-
-var math = {
-    getBaseLog(x, y) {//返回以 x 为底 y 的对数(即 logx y) .  Math.log 返回一个数的自然对数
-        return Math.log(y) / Math.log(x);
-    }
-    ,
-    convertVector : {
-        ZupToYup: function(e){//navvis -> 4dkk
-            return new THREE.Vector3(e.x,e.z,-e.y)
-        },
-        YupToZup: function(e){//4dkk -> navvis
-            return new THREE.Vector3(e.x,-e.z,e.y)
-        },
-        
-        
-    },
-    convertQuaternion: {
-        ZupToYup: function(e){//navvis -> 4dkk  //不同于convertVisionQuaternion
-            let rotation = new THREE.Euler(-Math.PI/2,0,0)   
-            let quaternion = new THREE.Quaternion().setFromEuler(rotation)
-            return e.clone().premultiply(quaternion)
-            //return new THREE.Quaternion(e.x,e.z,-e.y,e.w).multiply((new THREE.Quaternion).setFromAxisAngle(new THREE.Vector3(1,0,0), THREE.Math.degToRad(90)))
-        },
-        YupToZup: function(e){//4dkk -> navvis
-            let rotation = new THREE.Euler(Math.PI/2,0,0)
-            let quaternion = new THREE.Quaternion().setFromEuler(rotation)
-            return e.clone().premultiply(quaternion)
-        },
-        
-        
-    },
-	 
-    convertVisionQuaternion: function(e) {
-        return new THREE.Quaternion(e.x,e.z,-e.y,e.w).multiply((new THREE.Quaternion).setFromAxisAngle(new THREE.Vector3(0,1,0), THREE.Math.degToRad(90)))
-    },
-    invertVisionQuaternion : function(e) {//反转给算法部
-        var a = e.clone().multiply((new THREE.Quaternion).setFromAxisAngle(new THREE.Vector3(0,1,0), THREE.Math.degToRad(-90)))
-        return new THREE.Quaternion(a.x,-a.z,a.y,a.w)
-    },
-    //------------
-    
-    getVec2Angle : function(dir1,dir2){ 
-        return Math.acos( THREE.Math.clamp(this.getVec2Cos(dir1,dir2), -1,1) )  
-    },
-    getVec2Cos :  function(dir1,dir2){ 
-        return dir1.dot(dir2) / dir1.length() / dir2.length()    
-    },
-    getAngle:function(vec1, vec2, axis){//带方向的角度 vector3
-        var angle = vec1.angleTo(vec2)
-        var axis_ = vec1.clone().cross(vec2);
-        if(typeof axis == 'string'){
-            if(axis_[axis] < 0){
-                angle *= -1
-            }
-        }else{//vector3
-            if(axis_.dot(axis)< 0){
-                angle *= -1
-            }
-        }
-        
-        return angle
-    }, 
-    
-    closeTo : function(a,b, precision=1e-6){ 
-        let f = (a,b)=>{
-            return Math.abs(a-b) < precision;
-        } 
-          
-        if(typeof (a) == 'number'){
-            return f(a, b);
-        }else{
-            let judge = (name)=>{
-                if(a[name] == void 0)return true //有值就判断,没值就不判断
-                else return f(a[name],b[name])
-            }
-            return judge('x') && judge('y') && judge('z') && judge('w')  
-        } 
-        
-    }, 
-     
-
-    
-	toPrecision: function (e, t) {//xzw change 保留小数
-		var f = function (e, t) {
-			var i = Math.pow(10, t);
-			return Math.round(e * i) / i
-		}
-		if (e instanceof Array) {
-			for (var s = 0; s < e.length; s++) {
-				e[s] = f(e[s], t);
-			}
-			return e;
-		} else if (e instanceof Object) {
-			for (var s in e) {
-				e[s] = f(e[s], t);
-			}
-			return e;
-		} else return f(e, t)
-	},
-    isEmptyQuaternion: function(e) {
-        return 0 === Math.abs(e.x) && 0 === Math.abs(e.y) && 0 === Math.abs(e.z) && 0 === Math.abs(e.w)
-    },
-    projectPositionToCanvas: function(e, t, i) {
-        i = i || new THREE.Vector3,
-        i.copy(e);
-		var r = .5 * $('#player').width()
-			, o = .5 * $('#player').height();
-        return i.project(t),
-        i.x = i.x * r + r,
-        i.y = -(i.y * o) + o,
-        i
-    },
-     
-	
-	handelPadResize:false,
-	/* handelPadding : function () { //去除player左边和上面的宽高,因为pc的player左上有其他element  许钟文
-		
-		var pads = [];//记录下来避免反复计算
-		var index = [];
-		var resetPad = function(){
-			pads = []; 
-			index = [];
-			math.handelPadResize = false; //switchview时resized为true
-		}
-		
-		if(config.isEdit && !config.isMobile){
-			window.addEventListener('resize',resetPad);
-		}
-		return function(x, y, domE){
-			if(!config.isEdit || config.isMobile) {
-				return {
-					x: x,
-					y: y
-				}  
-			}
-			
-			if(this.handelPadResize)resetPad(); 
-			domE = domE || $('#player')[0];
-			var pad;
-			var i = index.indexOf(domE);
-			if (i == -1){ 
-				index.push(domE);
-				pad = {
-					x: this.getOffset("left", domE),
-					y: this.getOffset("top", domE)
-				}
-				pads.push(pad)  
-			}					
-			else pad = pads[i];
-			return {
-				x: x - pad.x,
-				y: y - pad.y
-			}
-		}
-		
-	}(),  */
-	
-	getOffset: function (type, element, parent) {//获取元素的边距 许钟文
-		var offset = (type == "left") ? element.offsetLeft : element.offsetTop;
-		if (!parent) parent = $("body")[0];
-		while (element = element.offsetParent) {
-			if (element == parent) break;
-			offset += (type == "left") ? element.offsetLeft : element.offsetTop;
-		}
-		return offset;
-	}
-
-	,
-    constrainedTurn: function(e) {
-        var t = e % (2 * Math.PI);
-        return t = t > Math.PI ? t -= 2 * Math.PI : t < -Math.PI ? t += 2 * Math.PI : t
-    },
-    getFOVDotThreshold: function(e) {
-        return Math.cos(THREE.Math.degToRad(e / 2))
-    },
-    transform2DForwardVectorByCubeFace: function(e, t, i, n) {
-        switch (e) {
-        case GLCubeFaces.GL_TEXTURE_CUBE_MAP_POSITIVE_X:
-            i.set(1, t.y, t.x);
-            break;
-        case GLCubeFaces.GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
-            i.set(-1, t.y, -t.x);
-            break;
-        case GLCubeFaces.GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
-            i.set(-t.x, 1, -t.y);
-            break;
-        case GLCubeFaces.GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
-            i.set(-t.x, -1, t.y);
-            break;
-        case GLCubeFaces.GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
-            i.set(-t.x, t.y, 1);
-            break;
-        case GLCubeFaces.GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
-            i.set(t.x, t.y, -1)
-        }
-        n && i.normalize()
-    },
-	
-	
-	
-	getFootPoint : function(oldPos, p1, p2, restricInline){ //找oldPos在线段p1, p2上的垂足
-		/* if(isWorld){//输出全局坐标 需要考虑meshGroup.position
-			p1 = p1.clone();
-			p2 = p2.clone();
-			p1.y += mainDesign.meshGroup.position.y;
-			p2.y += mainDesign.meshGroup.position.y;
-		} */
-        if(p1.equals(p2))return p1.clone()
-		var op1 = oldPos.clone().sub(p1); 
-		var p1p2 = p1.clone().sub(p2)
-		var p1p2Len = p1p2.length()
-		var leftLen = op1.dot(p1p2) / p1p2Len;
-		var pos = p1.clone().add(p1p2.multiplyScalar( leftLen/p1p2Len )); 
-         
-        if(restricInline && pos.clone().sub(p1).dot( pos.clone().sub(p2)   ) > 0){//foot不在线段上
-            if(pos.distanceTo(p1) < pos.distanceTo(p2)) pos = p1.clone();
-            else pos = p2.clone();
-        }
-        
-		return pos;
-	},
-
-	
-	
-	
-	
-	
-	/**
-   * 计算多边形的重心
-   * @param {*} points
-   */
-	getCenterOfGravityPoint : function(mPoints){
-		var area = 0.0;//多边形面积
-		var Gx = 0.0, Gy = 0.0;// 重心的x、y
-
-		for (var i = 1; i <= mPoints.length; i++) {
-			var ix = mPoints[i % mPoints.length].x;
-			var iy = mPoints[i % mPoints.length].y;
-			var nx = mPoints[i - 1].x;
-			var ny = mPoints[i - 1].y;
-			var temp = (ix * ny - iy * nx) / 2.0;
-			area += temp;
-			Gx += temp * (ix + nx) / 3.0;
-			Gy += temp * (iy + ny) / 3.0;
-		}
-		Gx = Gx / area;
-		Gy = Gy / area;
-		return { x: Gx, y: Gy };
-	},
-	
-	getBound : function(ring){
-		var bound = new THREE.Box2();
-		for(var j=0,len = ring.length; j<len; j++){
-			bound.expandByPoint(ring[j])
-		}
-		return bound;
-	},
-
-	isPointInArea : function(ring, holes, point, ifAtLine){//判断点是否在某个环内, 若传递了holes代表还要不能在内环内
-		var bound = this.getBound(ring);
-		if(point.x < bound.min.x || point.x > bound.max.x || point.y < bound.min.y || point.y > bound.max.y)return false;
-		
-		 
-		var inside = false;
-		var x = point.x,
-		  y = point.y;
-
-		for (var i = 0, j = ring.length - 1; i < ring.length; j = i++) {
-		  var xi = ring[i].x,
-			yi = ring[i].y;
-		  var xj = ring[j].x,
-			yj = ring[j].y;
- 
-		  if((xi - x)*(yj - y) == (xi - x)*(yi - y) && x>=Math.min(xi,xj) && x<=Math.max(xi,xj)//xzw add
-			  && y>=Math.min(yi,yj) && y<=Math.max(yi,yj)
-		  ){
-			  //return !!ifAtLine;//在线段上,则判断为…… (默认在外)
-              return {atLine:true}
-		  }
-		  
-		   if (((yi > y) != (yj > y)) &&
-			(x < (xj - xi) * (y - yi) / (yj - yi) + xi) 
-			) {
-			inside = !inside;
-		  } 
-		  
-		}
-        
-        if(inside && holes){
-            return !holes.some(ring=>this.isPointInArea(ring, null, point, ifAtLine) )   //不能存在于任何一个二级内环内
-        }else{
-            return inside;
-        }
-        
-
-		
-	},
-	
-	getArea : function (ring) { //求面积  顺时针为正  来自three shape
-		for (var t = ring.length, i = 0, n = t - 1, r = 0; r < t; n = r++)
-			i += ring[n].x * ring[r].y - ring[r].x * ring[n].y;
-		return -.5 * i
-	},
-	isInBetween : function(a, b, c, precision) {
-        // 如果b几乎等于a或c,返回false.为了避免浮点运行时两值几乎相等,但存在相差0.00000...0001的这种情况出现使用下面方式进行避免
-
-        /* if (Math.abs(a - b) < 0.000001 || Math.abs(b - c) < 0.000001) {
-            return false;
-        } 
- 
-        return (a <= b && b <= c) || (c <= b && b <= a);*/
-        
-        
-        //更改:如果b和a或c中一个接近 就算在a和c之间
-        return (a <= b && b <= c) || (c <= b && b <= a) || this.closeTo(a,b,precision) || this.closeTo(b,c,precision); 
-        
-    },
-	 
-    
-    ifPointAtLineBound:function(point, linePoints, precision){
-        //待验证  横线和竖线比较特殊
-        return  math.isInBetween(linePoints[0].x, point.x, linePoints[1].x, precision) && math.isInBetween(linePoints[0].y, point.y, linePoints[1].y, precision) 
-    }
-    
-    , 
-	
-	isLineIntersect: function (line1, line2, notSegment, precision) {//线段和线段是否有交点.  notSegment代表是直线而不是线段
-		var a1 = line1[1].y - line1[0].y;
-		var b1 = line1[0].x - line1[1].x;
-		var c1 = a1 * line1[0].x + b1 * line1[0].y;
-		//转换成一般式: Ax+By = C
-		var a2 = line2[1].y - line2[0].y;
-		var b2 = line2[0].x - line2[1].x;
-		var c2 = a2 * line2[0].x + b2 * line2[0].y;
-		// 计算交点		
-		var d = a1 * b2 - a2 * b1;
-
-		// 当d==0时,两线平行
-		if (d == 0) {
-		  return false;
-		} else {
-		  var x = (b2 * c1 - b1 * c2) / d;
-		  var y = (a1 * c2 - a2 * c1) / d;
-
-		  // 检测交点是否在两条线段上
-		  /* if (notSegment || (isInBetween(line1[0].x, x, line1[1].x) || isInBetween(line1[0].y, y, line1[1].y)) &&
-			(isInBetween(line2[0].x, x, line2[1].x) || isInBetween(line2[0].y, y, line2[1].y))) {
-			return {x,y};
-		  } */
-          if (notSegment ||  math.ifPointAtLineBound({x,y}, line1, precision) && math.ifPointAtLineBound({x,y}, line2, precision)){ 
-                return {x,y};
-		  }
-		}  
-    },
-     
-	getNormal2d : function(o={} ){//获取二维法向量 方向向内
-		var x,y, x1,y1; 
-		//line2d的向量
-        if(o.vec){
-            x1 = o.vec.x;  y1 = o.vec.y
-        }else{
-            x1 = o.p1.x - o.p2.x;
-            y1 = o.p1.y - o.p2.y;
-        }
-		
-		//假设法向量的x或y固定为1或-1
-		if(y1 != 0){
-			x = 1;
-			y = - (x1 * x) / y1;
-		}else if(x1 != 0){//y如果为0,正常情况x不会是0
-			y = 1;
-			x = - (y1 * y) / x1;
-		}else{
-			console.log("两个点一样");
-			return null;
-		}
-		
-		//判断方向里或者外:
-		var vNormal = new THREE.Vector3(x, 0, y);
-		var vLine = new THREE.Vector3(x1, 0, y1);
-		var vDir = vNormal.cross(vLine);
-		if(vDir.y>0){
-			x *= -1;
-			y *= -1;
-		} 
-		return new THREE.Vector2(x, y).normalize();
- 	},
-     
-    getQuaBetween2Vector:function(oriVec, newVec, upVec){ //获取从oriVec旋转到newVec可以应用的quaternion
-        var angle = oriVec.angleTo(newVec);
-        var axis = oriVec.clone().cross( newVec).normalize();//两个up之间
-        if(axis.length() == 0){//当夹角为180 或 0 度时,得到的axis为(0,0,0),故使用备用的指定upVec
-            return new THREE.Quaternion().setFromAxisAngle( upVec, angle );
-        }
-        return new THREE.Quaternion().setFromAxisAngle( axis, angle );
-    }
-    /* ,
-    getQuaBetween2Vector2 : function(oriVec, newVec   ){//not camera
-        var _ = (new THREE.Matrix4).lookAt( oriVec, new THREE.Vector3, new THREE.Vector3(0,1,0))
-        var aimQua = (new THREE.Quaternion).setFromRotationMatrix(_)
-        var _2 = (new THREE.Matrix4).lookAt( newVec, new THREE.Vector3, new THREE.Vector3(0,1,0))
-        var aimQua2 = (new THREE.Quaternion).setFromRotationMatrix(_2)
-        
-        return aimQua2.multiply(aimQua.clone().inverse()) 
-        
-    } */
-    
-        
-    ,
-    
-    getScaleForConstantSize : function(){ //获得规定二维大小的mesh的scale值。可以避免因camera的projection造成的mesh视觉大小改变。  来源:tag.updateDisc
-        var w;  
-        var i = new THREE.Vector3, o = new THREE.Vector3, l = new THREE.Vector3, c = new THREE.Vector3, h = new THREE.Vector3
-        return function(op={}){
-            if(op.width2d) w = op.width2d //如果恒定二维宽度
-            else{//否则考虑上距离,加一丢丢近大远小的效果
-                var currentDis, nearBound, farBound
-                if(op.camera.type == "OrthographicCamera"){
-                    currentDis = 200 / op.camera.zoom  //(op.camera.right - op.camera.left) / op.camera.zoom
-                }else{
-                    currentDis = op.position.distanceTo(op.camera.position);
-                } 
-                w = op.maxSize - ( op.maxSize -  op.minSize) * THREE.Math.smoothstep(currentDis,  op.nearBound,  op.farBound);
-                //maxSize : mesh要表现的最大像素宽度;   nearBound: 最近距离,若比nearBound近,则使用maxSize
-            }
-            i.copy(op.position).project(op.camera),  //tag中心在屏幕上的二维坐标
-            o.set(op.resolution.x / 2, op.resolution.y / 2, 1).multiply(i), //转化成px   -w/2 到 w/2的范围
-            l.set(w / 2, 0, 0).add(o),  //加上tag宽度的一半
-            c.set(2 / op.resolution.x, 2 / op.resolution.y, 1).multiply(l), //再转回  -1 到 1的范围
-            h.copy(c).unproject(op.camera);//再转成三维坐标,求得tag边缘的位置
-            var g = h.distanceTo(op.position)//就能得到tag的三维半径
-            //这里使用的都是resolution2, 好处是手机端不会太小, 坏处是pc更改网页显示百分比时显示的大小会变(或许可以自己算出设备真实的deviceRatio, 因window.screen是不会改变的),但考虑到用户可以自行调节字大小也许是好的
-            return g  //可能NAN  当相机和position重叠时
-        }
-    }()
-    ,
-    
-    //W , H, left, top分别是rect的宽、高、左、上
-    getCrossPointAtRect : function(p1, aim, W , H, left, top){//求射线p1-aim在rect边界上的交点,其中aim在rect范围内,p1则不一定(交点在aim这边的延长线上)
-        
-        var x,y, borderX;
-        var r = (aim.x - p1.x) / (aim.y - p1.y);//根据相似三角形原理先求出这个比值	
-        var getX = function(y){
-            return  r * (y-p1.y) + p1.x;
-        }
-        var getY = function(x){
-            return  1/r * (x-p1.x) + p1.y;
-        }
-        if(aim.x >= p1.x){ 
-            borderX = W+left;
-        }else{
-            borderX = left; 
-        }
-        x = borderX;
-        y = getY(x);
-        if(y < top || y > top+H){
-            if(y < top){
-                y = top; 
-            }else{
-                y = top+H; 
-            }
-            x = getX(y)			
-        }
-        return new THREE.Vector2(x, y);  
-    },
-    getDirFromUV : function(uv){ //获取dir   反向计算 - -  二维转三维比较麻烦 
-        var dirB; //所求 单位向量
-        
-        
-        
-        var y = Math.cos(uv.y * Math.PI);              //uv中纵向可以直接确定y,  根据上面getUVfromDir的反向计算 
-                            // 故 uv.y * Math.PI  就是到垂直线(向上)的夹角
-        var angle = 2 * Math.PI * uv.x - Math.PI       //x/z代表的是角度
-
-        var axisX, axisZ; //axis为1代表是正,-1是负数
-        if (-Math.PI <= angle && angle < 0) {
-            axisX = -1 //下半圆
-        } else {
-            axisX = 1 //上半圆
-        }
-        if (-Math.PI / 2 <= angle && angle < Math.PI / 2) {
-            axisZ = 1 //右半圆
-        } else {
-            axisZ = -1 //左半圆
-        }
-
-
-
-        var XDivideZ = Math.tan(angle);
-        var z = Math.sqrt((1 - y * y) / (1 + XDivideZ * XDivideZ));
-        var x = XDivideZ * z
-
-
-        if (z * axisZ < 0) { //异号
-            z *= -1;
-            x *= -1;
-            if (x * axisX < 0) {
-          //      console.log("wrong!!!!!??????????")
-            }
-        }
-
-        x *= -1 //计算完成后这里不能漏掉 *= -1	
-        dirB = this.convertVector.YupToZup(new THREE.Vector3(x, y, z))   
-
-        //理想状态下x和z和anotherDir相同
-        return dirB
-
-
-    },
-    
-    getUVfromDir : function(dir) { //获取UV  同shader里的计算 
-        var dir = this.convertVector.ZupToYup(dir)
-        dir.x *= -1; //计算前这里不能漏掉 *= -1  见shader
-        var tx = Math.atan2(dir.x, dir.z) / (Math.PI * 2.0) + 0.5; //atan2(y,x) 返回从 X 轴正向逆时针旋转到点 (x,y) 时经过的角度。区间是-PI 到 PI 之间的值
-        var ty = Math.acos(dir.y) / Math.PI;
-        return new THREE.Vector2(tx,  ty)  
-
-        //理想状态下tx相同
-    },
-     
-    getDirByLonLat : function(lon,lat){
-        var dir = new THREE.Vector3
-        var phi = THREE.Math.degToRad(90 - lat);
-        var theta = THREE.Math.degToRad(lon);
-        dir.x = Math.sin(phi) * Math.cos(theta);
-        dir.y = Math.cos(phi);
-        dir.z = Math.sin(phi) * Math.sin(theta);   
-        return dir
-    } //0,0 => (1,0,0)     270=>(0,0,-1)
-    ,    
-    projectPointAtPlane:function(o={}){//获取一个点在一个面上的投影 {facePoints:[a,b,c], point:}
-        var plane = new THREE.Plane().setFromCoplanarPoints(...o.facePoints)
-        return plane.projectPoint(o.point, new THREE.Vector3() )
-    }
-    ,
-    
-    getPolygonsMixedRings:function( polygons,  onlyGetOutRing){//{points:[vector2,...],holes:[[],[]]} 
-         
-         
-        let points = [] 
-        let lines = []
-        let i = 0 
-        
-        polygons.forEach(e=> points.push(...e.map(a=>new THREE.Vector2().copy(a) )) )   
-        polygons.forEach((ps,j)=>{
-            let length = ps.length;
-            let index = 0;
-            while(index<length){
-                lines.push({p1:index+i,p2:(index+1)%length+i});
-                index ++;
-            }
-            i+=length
-        })
-    
-             
-        points.forEach((p,j)=>{p.id = j}) 
-            
-        let rings = searchRings({
-            points,
-            lines,
-            onlyGetOutRing    
-        })
-        //console.log(rings)
-        
-        rings = rings.filter(e=>e.closetParent == void 0)// 子环不加,被外环包含了
-        
-        return rings 
-        
-    },
-
-    getQuaFromPosAim( position, target ){ 
-        let matrix = (new THREE.Matrix4).lookAt(position, target, new THREE.Vector3(0,0,1))
-        return (new THREE.Quaternion).setFromRotationMatrix(matrix)
-        
-    },
-    
-    
-    getBoundByPoints(points, minSize){ 
-        var bound = new THREE.Box3
-        points.forEach(point=>{
-            bound.expandByPoint(point)
-        }) 
-        let center = bound.getCenter(new THREE.Vector3)
-        if(minSize){
-            let minBound = (new THREE.Box3()).setFromCenterAndSize(center, minSize)
-            bound.union(minBound)
-        }
-        return {
-            bounding:bound,
-            size: bound.getSize(new THREE.Vector3),
-            center,
-        }
-    },
-
-
-
-};
-
- 
-Potree.math = math
-
-
-export default math

+ 0 - 879
src/utils/searchRings.js

@@ -1,879 +0,0 @@
-import * as THREE from "../../libs/three.js/build/three.module.js";
-import math from "./math.js";
-
-var points = [];
-var lines = [];
-var rings = []; 
- 
-var precision = 0.1 //容错精度 //正常是0.01 但是在编辑时容易出现交错的线看不出来,导致需要getSliceLines 然后多出新增点
- 
- 
-var getPoint = function(o, type){
-    var point;
-    if(typeof o == "string" || typeof o == "number")point = points.find(p=> p.ids.includes(o));
-    else{
-        point = points.find(p=> math.closeTo(p.x , o.x, precision) && math.closeTo(p.y , o.y, precision)   ) 
-        if(!point) point = new Point(o.x, o.y,{record:true, id:o.id}, type) 
-        else{ 
-            //console.log('addPoint', point, o)
-            point.addPoint(o.id)
-        }
-    }
-    if(!point){
-        console.log("no point!")
-    }
-    
-    
-    return point
-}
-
-var getLine = function(id){
-    return lines.find(line=> line.ids.includes(id));
-}
-
-
-
-var getAngleInfo = function(points){
-    var info = {}
-    info.angle = points[1].clone().sub(points[0]).angle(); 
-    if(math.closeTo(info.angle, Math.PI*2)){ //如360-0.01  
-        info.angle -= Math.PI*2;    //有可能得到负数-0.001
-    }else if(info.angle > Math.PI || math.closeTo(info.angle, Math.PI)){//如180+-0.01
-        info.angle -= Math.PI;
-        info.reverse = true
-    } 
-    return info  //结果大约是 0 - 3.14
-}
-
-class Point extends THREE.Vector2{
-    constructor(x, y, o={}){
-        super(x, y);
-        
-        if(o.record){   
-            this.id = o.id;
-            if(this.id == void 0) this.id = "add_"+points.length 
-            this.ids =  [this.id] ;//存储拥有该坐标的点原始数据的id
-            points.push(this)  
-        }  
-        
-        this.type = o.type || "" 
-        this.lines = [];
-          
-    }
-    
-    addPoint(id){
-        this.ids.push(id)
-    }
-    
-    searchLineByFactor(dir, type, comeLine){
-        
-        var lines = this.lines.filter(line=>line.searchTime<2)
-        
-        if(lines.length==0)return;
-        else if(lines.length==1)return lines[0];
-        else lines = lines.filter(line=>line!=comeLine)
-        
-        if(lines.length==1)return lines[0];
-        
-        var result; 
-        lines.forEach(line=>{
-            var vec = line.getVector();
-            if(line.points[1] == this) vec.negate();
-            var factor = math.getVec2Angle(dir, vec);
-            
-            if(new THREE.Vector3(dir.x, dir.y, 0).cross(new THREE.Vector3(vec.x, vec.y, 0)).z<0) factor*= -1  /////
-             
-            if(!result){
-                result = {line, factor}
-            } 
-            else{
-                if(type == "min" && factor<result.factor || type == "max" && factor>result.factor) result = {line, factor}
-            }
-        })
-        return result.line;
-    }
-} 
- 
-var lineLen=0;
-class Line{
-    constructor(o){  
-        if(o.points[0] == o.points[1])return; 
-        this.points = o.points;
-        this.type = o.type || 'line'
-        
-        if(this.type == 'line'){
-            var oldLine = lines.find(line=>line.points.includes(o.points[0]) && line.points.includes(o.points[1]))
-            if(oldLine){
-                o.id != void 0 && oldLine.ids.push(o.id)
-                return oldLine;
-            }
-            this.id = o.id == void 0 ? ("line"+lineLen ++) : o.id
-            this.ids = [this.id]
-           
-            o.dontWriteToPoint || this.points.forEach((point)=>{point.lines.push(this)})
-            o.isChild || lines.push(this);
-            this.searchTime = 0 // 最多两次
-        } 
-         
-        this.children = [];//分割
-        this.parents = [];//分割
-        this.match = [];
-         
-        
-    }
-    
-    
-    getAngleInfo(){ 
-        var angleInfo = getAngleInfo(this.points)
-        this.angle = angleInfo.angle
-        this.reverse = angleInfo.reverse
-    }
-    
-    getIntersectWithLine(line, precision){
-        var joint = line.points.find(point=>this.points.includes(point))
-        if(joint)return {point:joint, type:"joint"};
-        
-        var intersect = math.isLineIntersect( line.points , this.points , false, precision );
-        if(intersect) return {point: intersect, type:"intersect"};
-        
-        
-    } 
-    
-    writeToPoint(){
-        this.points.forEach((point)=>{point.lines.includes(this) || point.lines.push(this)})
-    }
-    
-    checkIfParent(line){ 
-        if(this == line){ 
-            return true;//原因就是slice的点和端点很近  误差导致 
-        }
-        else return this.parents.find(e=>e.checkIfParent(line))
-        
-    }
-    
-    splitByPoint(point){
-        var line1 = new Line({points:[point, this.points[0]],  dontWriteToPoint:true, hasntsure:true})
-        var line2 = new Line({points:[point, this.points[1]],  dontWriteToPoint:true, hasntsure:true})
-        
-        if(!line1.points || !line2.points){//有至少一个是点相同的,没写到group.lines里
-            
-            console.warn('splitByPoint 线有点相同')
-            return;
-        }
-        
-        if(this.checkIfParent(line1)||this.checkIfParent(line2) || line1.checkIfParent(this) || line2.checkIfParent(this)){
-            console.warn("splitByPoint 发现parent和children一样")//,请检查getSliceWalls,尤其 if(math.closeTo(line1.angle,line2.angle)){ 处
-
-            return;
-        }
-        var deal = (line)=>{ 
-            this.children.push(line);
-            line.parents.push(this)  
-             
-            if(!lines.includes(line))lines.push(line)
-            line.writeToPoint()    
-            
-        }
-        deal(line1)
-        deal(line2)
-         
-        var index = this.points[0].lines.indexOf(this);
-        index > -1 && this.points[0].lines.splice(index,1)
-        var index = this.points[1].lines.indexOf(this);
-        index > -1 && this.points[1].lines.splice(index,1)
-         
-        
-        return [line1,line2]
-    }
-    splitByPoints(points){
-        points = points.map(point=>{return {dis:point.distanceTo(this.points[0]), point:point}})
-        points.sort((point1, point2)=>{return point1.dis - point2.dis})
-        var children = [];
-        
-        
-        points.forEach((point, index)=>{
-            var line1 = new Line({points:[point.point, index==0?this.points[0]:points[index-1].point ],group:this.group , dontWriteToPoint:true, hasntsure:true})
-            children.push(line1)  
-        })
-        var line2 = new Line({points:[points[points.length-1].point, this.points[1] ],group:this.group , dontWriteToPoint:true, hasntsure:true})
-        children.push(line2); 
-        
-        
-         
-        var a = children.find(line=> !line.points ||  this.checkIfParent(line) || line.checkIfParent(this))
-        if(a){
-            console.error("splitByPoints  return")
-            return;
-        }
-         
-        
-        children.forEach(line=>{  
-            this.children.push(line);
-            line.parents.push(this)   
-            
-            if(!lines.includes(line))lines.push(line)
-            line.writeToPoint()   
-            line.writeToPoint() 
-        })
-        
-        var index = this.points[0].lines.indexOf(this);
-        index > -1 && this.points[0].lines.splice(index,1)
-        var index = this.points[1].lines.indexOf(this);
-        index > -1 && this.points[1].lines.splice(index,1)
-        
-         
-    }  
-    
-    
-    getAllSlices(){//如果有被分割的片段 就返回片段,否则返回自身
-        var children = [];
-        var traverse = function(elem){
-            if(elem.children.length == 0) children.push(elem) 
-            else elem.children.forEach(traverse)
-        }
-        traverse(this)
-        return children
-    }
-    getVector(){
-        return this.points[1].clone().sub(this.points[0]);
-    }
-    
-    getLength(){
-        return this.points[0].distanceTo(this.points[1])
-    }
-    
-    getCenter(){
-        return this.points[1].clone().add(this.points[0]).multiplyScalar(.5);
-    }
-} 
-var getMixedSet = function(arr1, arr2){//交集
-    return arr1.filter(item=>arr2.includes(item));
-}
-var getUnionSet = function(arr1, arr2){//并集
-    return arr1.concat(arr2.filter(item=>!arr1.includes(item)))
-}
-var getDifferenceSet = function(arr1, arr2){//差集
-    var arr11 = arr1.filter(item=>!arr2.includes(item));
-    var arr22 = arr2.filter(item=>!arr1.includes(item));
-    return arr11.concat(arr22)
-}
-var getDifferenceSetMuti = function(arr){//收集绝对没有重复的元素,也就是判断出现次数=1的
-    var set = [];
-    arr.forEach(arr1=>{
-        arr1.forEach(item=>{
-            var index = set.indexOf(item)
-            if(index>-1){
-                set.splice(index, 1)
-            }else{
-                set.push(item)
-            }
-        })
-    })
-    return set;
-} 
-
-function DoorAtWhichLine(points, lines){
-    var mid = points[0].clone().add(points[1]).multiplyScalar(0.5)
-    lines = lines.filter(line=>math.ifPointAtLineBound(mid, line.points, precision))
-    if(lines.length == 0)return
-    var result = {line:null, dis:Infinity}
-    lines.forEach(line=>{
-        var foot = math.getFootPoint(mid, line.points[0], line.points[1] )
-        var dis = foot.distanceTo(mid)
-        if(dis<result.dis){
-            result.line = line; result.dis = dis
-        }
-    })
-    return result
-    
-}
-
-
-
-
-var ringLen = 0;
-class Ring{
-    constructor(o){
-        this.id = ringLen ++
-        this.type = o.type || 'normal';
-        this.points = o.points;
-        this.lines = o.lines;     
-        rings.push(this); 
-        this.child = []//包含的环
-        this.parent = []//被包含的环
-        this.smallNeibours = []//相邻最小环(存在和它有一个以上的相同边的最小环)
-        
-        var area = math.getArea(this.points);
-        this.area = Math.abs(area)
-        this.isClockwise = area<0//是否逆时针。一般都是逆时针得到的,如果是顺时针,可能是贪吃蛇的情况,可能不是最小环,需要去掉。
-    } 
-    
-}
-var findLine = function(p1,p2){
-    return lines.find(line=>line.points.includes(p1) && line.points.includes(p2)  )
-}
-var ifSamePart = function(checkPart , part){//checkPart中所包含的part片段是否和基准part的顺序一样(逆序也可以, 中间有其他数也可以,起始不同也行。比如 01234和204一样的)
-    var axis, startIndex, newCheckPart=[];
-     
-     
-    for(var j=0,len1 = checkPart.length; j<len1; j++){//将checkPart中比part多的数除去,使两个数组中包含的数完全相同。
-        if(part.indexOf(checkPart[j])>-1)newCheckPart.push(checkPart[j]);
-    }
-
-    for(var i=0,len = part.length; i<len; i++){
-        var index = newCheckPart.indexOf(part[i]);
-        if(index == -1)return false;
-        if(i == 0) startIndex = index;//标记第一个查找点对应的index 
-        else if(i == 1){//标记查找顺序是正还是逆
-            axis = index - startIndex;
-            if(axis == len - 1) axis = -1;//刚好是首和尾
-            else if(axis == 1- len) axis = 1;
-            
-            if(axis != -1 && axis != 1){
-                return false
-            }  
-        }else{//判断是否是按顺序的
-            if(index != ((startIndex+axis * i + len) % len) ) return false;
-        } 
-    }
-    return {sameAxis:axis>0};	//如果一样的话返回正逆是否相同		
-}
-
-//或者判断是否有相同边(但是相同点是可以组成不同环)
-var ifSameRing = function(ring1, ring2){//判断两个环是否相等。 除了可以逆向外顺序要对
-    if(ring1 instanceof Ring)ring1 = ring1.points;
-    if(ring2 instanceof Ring)ring2 = ring2.points;
-    if(ring1.length != ring2.length)return false;
-    if(ring1.lines && ring2.lines){
-        if(getDifferenceSet(ring1.lines , ring2.lines).length == 0)return true;//差集个数为0
-    }else{
-        if(ifSamePart(ring1, ring2))return true 
-    }
-    
-}
-  
- 
-
-var atWhichChildLine = function(point, line, precision){
-    if(line.children.length == 0){//这里可能要放低精度 保证能找到
-        if(math.ifPointAtLineBound(point, line.points, precision)) return line;
-           
-    }else{
-        for(var i=0;i<line.children.length;i++){
-            var at = atWhichChildLine(point, line.children[i], precision)
-            if(at)return at
-        }
-    }
-}
-
-
-
-function getSliceLines(){
-    var len = lines.length;
-     
-     
-    var deal = function(line1,line2){
-        if(line1 == line2)return;
-        
-        if(line1.angle == void 0) line1.getAngleInfo()
-        if(line2.angle == void 0) line2.getAngleInfo()
-            
-        var intersect = line1.getIntersectWithLine(line2, precision);
-        if(intersect){
-            var point //得到交点
-            if(intersect.type == "intersect"){
-                point = getPoint(intersect.point, "whenGetSliceLines");
-         
-                var line1_ = atWhichChildLine(point, line1)
-                var line2_ = atWhichChildLine(point, line2)
-                //重合的情况还没考虑(平行)
-                if(!line1_) line1_ = atWhichChildLine(point, line1, precision)//降低精度
-                if(!line1_) line1_ = atWhichChildLine(point, line1, precision*2)//降低精度
-                if(!line2_) line2_ = atWhichChildLine(point, line2, precision)
-                if(!line2_) line2_ = atWhichChildLine(point, line2, precision*2)//降低精度
-                //拆分线条:
-                
-                //如果还报错,找不到ChildLine,就直接返回吧  或者搞个循环 逐渐降低精度
-                if(!line1_ || !line2_){
-                    console.warn("atWhichChildLine仍旧找不到 :" + line1.id + ',' + line2.id + ", pointId: "+point.id)
-                    line1_ || console.warn("找不到line1")
-                    line2_ || console.warn("找不到line2")
-                    return;
-                }
-                
-                if(line1_.points.find(p=>p == point) && line2_.points.find(p=>p == point)){//这个点是line1_、 line2_端点,不做处理
-                    //console.log("joint型  "+point.id)
-                }else if(line1_.points.find(p=>p == point)){//T型交叉 
-                    line2_.splitByPoint(point)//加入到母线中,之后还先用母线判断交点
-                    //console.log("T型交叉1 "+point.id)
-                }else if(line2_.points.find(p=>p == point)){//T型交叉 
-                    line1_.splitByPoint(point)
-                    //console.log("T型交叉2 "+point.id)
-                }else{//十字交叉 
-                    line1_.splitByPoint(point)
-                    line2_.splitByPoint(point)
-                }     
-            }else{
-                point = intersect.point//交点是端点 
-                if(math.closeTo(line1.angle,line2.angle)){ //重合一部分
-                    var children1 = line1.getAllSlices()
-                    var children2 = line2.getAllSlices();
-                    if(children1.length>1 || children2.length>1){  //使用最小分割片段来比较
-                        children1.forEach(child1=>{
-                            children2.forEach(child2=>{
-                                deal(child1, child2)
-                            }) 
-                        })
-                        return;
-                    }
-                
-                    var anotherPoint1 = line1.points.find(point_=>point_!=point)
-                    var anotherPoint2 = line2.points.find(point_=>point_!=point)
-                    if(math.ifPointAtLineBound(anotherPoint1, line2.points)){
-                        line2.splitByPoint(anotherPoint1)
-                    }else if(math.ifPointAtLineBound(anotherPoint2, line1.points)){
-                        line1.splitByPoint(anotherPoint2)
-                    }
-                } 
-                
-            }
-            
-        }else if(math.closeTo(line1.angle,line2.angle)){
-            var vec1 = line1.getVector()
-            var vec = line1.points[0].clone().sub(line2.points[0]);
-            var cos = math.getVec2Cos(vec1, vec);
-            if(math.closeTo(cos, -1, 1e-4) || math.closeTo(cos, 1, 1e-4)){ //共线
-            
-                var children1 = line1.getAllSlices()
-                var children2 = line2.getAllSlices();
-                if(children1.length>1 || children2.length>1){  //使用最小分割片段来比较
-                    children1.forEach(child1=>{
-                        children2.forEach(child2=>{
-                            deal(child1, child2)
-                        }) 
-                    })
-                    return;
-                }
-                
-                //判断是否重叠 
-                var A = line1.points[0]; 
-                var C = line1.reverse == line2.reverse ? line2.points[0] : line2.points[1]; 
-                 
-                var B = line1.points[1];
-                var D = line1.reverse == line2.reverse ? line2.points[1] : line2.points[0];
-                 
-                var BC = C.clone().sub(B) 
-                var AD = D.clone().sub(A)
-                if(BC.length()<AD.length()){
-                    var BA = A.clone().sub(B); 
-                    if(math.getVec2Angle(BC, BA) >= 1.57 )return;//没有重叠部分
-                }else{
-                    var AB = B.clone().sub(A)
-                    if(math.getVec2Angle(AD, AB) >= 1.57 )return;
-                }
-            
-            
-            
-                var f = function(line1,line2){
-                    var one = math.ifPointAtLineBound(line1.points[0], line2.points);
-                    var two = math.ifPointAtLineBound(line1.points[1], line2.points);
-                    if(one && two){//line1在line2上
-                        line2.splitByPoints( line1.points )
-                        return true
-                    }else if(one || two){//错开
-                        var point1 = one ? line1.points[0] : line1.points[1];
-                        var anotherPoint1 = one ? line1.points[1] : line1.points[0];
-                        var dis1 = line2.points[0].distanceTo(anotherPoint1);
-                        var dis2 = line2.points[1].distanceTo(anotherPoint1); 
-                        var point2 = dis1 < dis2 ? line2.points[0] : line2.points[1]
-                        line1.splitByPoint(point2) 
-                        line2.splitByPoint(point1)
-                        return true
-                    }
-                }
-                f(line1, line2) || f(line2, line1)
-            }
-        }
-    
-    }
-     
-    for(let i=0;i<len;i++){
-        let line1 = lines[i];
-        for(let j=i+1;j<len;j++){ 
-            let line2 = lines[j];
-            deal(line1,line2)
-           
-        }
-    }
-    
-    //console.log("原有线条个数:"+len)
-    
-    //lines = lines.filter((line)=>{return line.children.length == 0})
-    
-    //console.log("现有线条个数:"+lines.length)
-    
-}
-var bound = new THREE.Box2()
-var build = function(o){
-    //融合了相近点
-    //根据bound 处理precision
-    o.points.forEach(p=>{
-        bound.expandByPoint(new THREE.Vector2(p.x,p.y))
-    })
-     
-    
-    if(o.precision != void 0){
-        precision = o.precision
-    }else{
-        var boundSize = bound.getSize(new THREE.Vector2)
-        precision = THREE.Math.clamp(Math.max(boundSize.x, boundSize.y) / 70, 0.2, 2);
-    }
-    
-    
-    
-    
-    
-    
-    
-    o.points.forEach(point=>getPoint(point))//{x:..,y:..}
-     
-        
-    o.lines.forEach(line=>{ //{p1:id1. p2:id2}
-        new Line({points:[getPoint(line.p1), getPoint(line.p2)], id:line.id })
-    })
-    //注意:不能出现一条线的两个点坐标一致,否则寻路时方向出错。 所以手动融合下相近点。
-}
-  
- 
-var searchRings = function(o={}){
-    points = [];
-    lines = [];
-    rings = [];
-    lineLen = ringLen = 0
-    o.points = o.points || []
-    o.lines = o.lines || []
-    
-     
-    build(o)
-    
-    if(!o.dontSliceLines){ 
-        getSliceLines()
-    }
-    
-    
-    
-    
-    
-    //查找最小回路:
-    //参考: 引入方向因子的最小回路、最大回路搜索算法.pdf 
-    //方法:  逆时针寻找(标记)最外层大环 -->从走过的点开始逆时针寻找最小环(直到所有可走的路被走过两次)-->逆时针寻找最外层大环(直到所有可走的路被走过两次)-->..
-    //其中找大环时选择方向因子最小的路, 而小环则相反(但只有开始第一条路是一样的, 都是选择最左边的点的因子最小的路)。  
-    //标记方法: 每条线需要被搜索两次才算完毕。搜索完毕的线退出搜索。(依据:搜索完全部最小回路后 , 在无向图中删除搜索过 2 次的边及孤立节点得到退化图 , 恰好构成最大回路。)  
-    var searchTime = 0;
-    var addRingJudgeCount = 0
-    var addRingJudge = function(ring, lines, connectedLines, type){// 处理拣出的片段 
-        addRingJudgeCount++;
-        
-        //console.log("addRingJudge points("+ type+"):"+  ring.map(point=>point.id) )
-        if(o.onlyGetOutRing && type == "small")return
-        
-        if(type == "small" || o.onlyGetOutRing){//挑出回路:
-            var newRings = []
-            while(ring.length){
-                var road = [];
-                var turnBack = false;
-                for(let i=0;i<ring.length;i++){
-                    if(road.includes(ring[i])){//如果走到方才的点,可能形成回路。 无论是不是回路都要摘去这段。
-                        var index = road.indexOf(ring[i])
-                        var pointArr = ring.slice(index, i);
-                        var linesArr = lines.slice(index, i);
-                        ring.splice(index,i-index);
-                        lines.splice(index,i-index);
-                        if(pointArr.length>2){// 如果只有两个数,代表原路返回, 如 1->2(->1) 
-                            if( !rings.find(ring_=>ifSameRing(pointArr, ring_))) newRings.push( new Ring({points: pointArr, lines:linesArr}) )
-                        }
-                        turnBack = true
-                        break;
-                    }else{
-                        road.push(ring[i])
-                        turnBack = false
-                    } 
-                }
-                if(!turnBack){//没有重复的点,那么就直接处理整条。
-                    if(ring.length>2){// 如果只有两个数,代表原路返回, 如 1->2(->1) 
-                        if( !rings.find(ring_=>ifSameRing(ring, ring_))) newRings.push( new Ring({points: ring, lines}) )
-                    }
-                    break;
-                }
-            } 
-            
-            if(type != 'small'){
-                newRings.forEach(e=>e.isOutRing = true)
-            }
-            
-            
-            //console.log(newRings)
-        }else{
-            return ring
-        }
-    }
-
-     
-   
-
-    var search = function(point2d, comeRoad, type, connectedLines){
-        searchTime++
-        var goLine; 
-        var direction;
-        if(type.includes("big")){  
-            if(!comeRoad){
-                if(type.includes("Left")){//逆时针
-                    direction = new THREE.Vector2(1,0);
-                }else{
-                    direction = new THREE.Vector2(-1,0);
-                }
-                goLine = point2d.searchLineByFactor(direction,"min") 
-            }else{
-                var lastPoint = comeRoad.points[comeRoad.points.length-1]
-                direction = point2d.clone().sub(lastPoint);
-                goLine = point2d.searchLineByFactor(direction,"min", findLine(point2d, lastPoint)) 
-            }
-            
-        }else{ 
-            if(!comeRoad){
-                //似乎找最小环时,第一条线也是找最小的因子,这样才能保证逆时针(除非只有顺时针一条路)
-                direction = new THREE.Vector2(1,0);
-                goLine = point2d.searchLineByFactor(direction,"min")  
-                
-            }else{
-                var lastPoint = comeRoad.points[comeRoad.points.length-1]
-                direction = point2d.clone().sub(lastPoint);
-                goLine = point2d.searchLineByFactor(direction,"max", findLine(point2d, lastPoint))
-            } 
-        }
-        if(!goLine)return 
-        
-        
-        goLine.searchTime++;
-        connectedLines.includes(goLine) || connectedLines.push(goLine)
-         
-             
-        var nextPoint = goLine.points.find( point => point2d!=point )
-        
-        //if( comeRoad && comeRoad.points[comeRoad.points.length - 1] == nextPoint ) return;//不能查找来时的方向(反方向)
-        //走不通就原路返回
-        
-        var roadPoints = comeRoad ? comeRoad.points.concat([point2d]) : [point2d];//每个分叉都能构成一条新的road
-        var roadLines = comeRoad ?  comeRoad.lines.concat([goLine]) : [goLine];
-        
-        
-        
-        
-        //走到第一个点就算停止,这时候可能得到一个环、或者一段走了两遍的线、或者一条线上带了些环。 
-        if(nextPoint == roadPoints[0]) return addRingJudge(roadPoints, roadLines, connectedLines, type) //形成环 
-        else{ 
-            /* var len = roadPoints.indexOf(nextPoint);
-            if( len > -1){ //走到走过的路的某一点 构成这段路的回路
-                var points = roadPoints.slice(len, roadPoints.length);
-                var lines = roadLines.slice(len, roadPoints.length);
-                addRingJudge(points, lines)    
-            }else{ */
-                return search(nextPoint,  {lines:roadLines, points:roadPoints}, type, connectedLines);//继续寻路
-            //}  
-        }
-         
-    }
-     
-
-    while(1){//搜寻一次大环
-        var connectedLines = [];//被搜寻过的且searchTime<2的线。一旦全部搜完就说明该连通区域搜寻完毕,继续查下一个连通区域。
-        var startPoint = null
-        points.forEach(point=>{//找出x最小的点
-            if(!point.lines.find(line=>line.searchTime<2))return;
-            if(!startPoint)startPoint = point
-            else if(point.x < startPoint.x)startPoint = point;
-        })
-        if(!startPoint)break; //说明全部找完
-        
-        
-        var ring = search(startPoint, null, "bigLeft", connectedLines)//逆时针  
-        //search(startPoint, null, "bigRight", connectedLines);//顺时针(为了防止最外层不是回路之前写了顺时针,但如果是回路就会走重复。后来发现只要逆时针即可,因为走完后剩下的可以再次找大环)
-        
-        connectedLines = connectedLines.filter(line=>line.searchTime<2)
-        
-        
-        
-        
-        while(connectedLines.length>0){//目标是顺着connectedLines把所有连通的小环都找到
-            
-            let points_ = [];//connectedLines中所有的点
-            connectedLines.forEach(line=>line.points.forEach(point=>{if(!points_.includes(point))points_.push(point) }))
-            var startPoint = null
-            points_.forEach(point=>{//找出x最小的点
-                if(!point.lines.find(line=>line.searchTime<2))return;
-                if(!startPoint)startPoint = point
-                else if(point.x < startPoint.x)startPoint = point;
-            })
-            if(!startPoint)break;
-            
-             
-            search(startPoint, null, "small", connectedLines)
-            
-            connectedLines = connectedLines.filter(line=>line.searchTime<2)
-        }   
-    } 
-    
-    
-    
-    /* if(o.onlyGetOutRing){
-        rings = rings.filter(e=>e.isOutRing)   
-    } */
-    
-    //console.log("searchTime "+searchTime + ", addRingJudgeCount " +addRingJudgeCount)
-    
-    
-   
-    
-    //找出所有的相邻关系,包括公共边 
-    var len = rings.length;
-    for(let i=0; i<len; i++){
-        let ring1 = rings[i] 
-        for(let j=i+1; j<len; j++){
-            let ring2 = rings[j]
-            var bothHasLines = getMixedSet(ring1.lines, ring2.lines) 
-            if(bothHasLines.length){//ring1oíring2?àáú
-                ring1.smallNeibours.push(ring2)
-                ring2.smallNeibours.push(ring1) 
-            }else{ 
-            }  
-        }
-    }
-    rings.forEach(ring1=>{
-        for(let i=0; i<len; i++){
-            var ring2 = rings[i];
-            if(ring1 == ring2 || ring1.smallNeibours.includes(ring2))continue;
-            
-            let inside
-            for(let u=0;u<ring1.points.length;u++){
-                inside = math.isPointInArea(ring2.points, null, ring1.points[u]);
-                if(!inside)break
-                else if(inside && !inside.atLine){
-                    break
-                }
-            } 
-             
-            
-            if(inside){  //只要其中一个点在ring2内,就说明ring1是内环          
-                if(inside.atLine){//(还是会存在点全在线上的情况,这时候判断中心点)  
-                    var center = math.getCenterOfGravityPoint(ring1.points)
-                    let inside1 = math.isPointInArea(ring2.points, null, center);
-                    if(!inside1){
-                        continue
-                    }
-                }
-                
-                ring2.child.push(ring1);
-                ring1.parent.push(ring2)
-            }
-        }
-    })
-    //去除非最小的ring  是否应该检测parent child?
-     /* 
-        like this: 
-        |———————————————————————|
-        |———|———————|———————|   |
-        |   |       |       |   |
-        |   |———————|———————|   |
-        |———————————————————————|
-    */
-    var wiseRings = rings.filter(r=>!r.isClockwise)//一般都是逆时针得到的,如果是顺时针,可能是贪吃蛇的情况,可能不是最小环,需要去掉。 
-    if(wiseRings.length > 0){
-        //console.log('%c存在非最小的ring! 进行处理:',"color:#00f"); 
-        wiseRings.forEach(ring=>{ //(此案例验证出smallNeibours就是它的最小构成,可以再看看别的案例)
-            if(ring.smallNeibours.length>0){//另:如果内部只有一个,说明它是最小环,不需要处理
-                var is = false
-                var difference = getDifferenceSet(ring.lines , getDifferenceSetMuti(ring.smallNeibours.concat(ring.child).map(ring=>ring.lines)))//获取所有smallNeibours和child的边中没有重复过的边(就是outline) 和该ring的线比较
-                 
-                
-                is = difference.every(line=> ring.child.find(r=>r.lines.includes(line))  )  //多出的线只能是child中的线
-                
-                if(is){
-                    console.log('%c删除非最小环 ring'+ring.id,"color:#00f");
-                    console.log(ring)
-                    rings.splice(rings.indexOf(ring), 1) 
-                    ring.child.forEach(c=>{var index = c.parent.indexOf(ring);index>-1 && c.parent.splice(index,1)})
-                    ring.parent.forEach(c=>{var index = c.child.indexOf(ring);index>-1 && c.child.splice(index,1)})
-                    ring.smallNeibours.forEach(c=>{var index = c.smallNeibours.indexOf(ring);index>-1 && c.smallNeibours.splice(index,1)})
-                }
-                
-            }
-            
-        })
-    }
-    
-    
-    
-    /* rings = rings.filter(ring=>{ 
-        rings = rings.filter(ring=>{ 
-            var enoughSize = ring.area > 0.5
-            if(!enoughSize){console.log('因面积过小去除ring '+ring.id + " , area: "+ring.area)}
-            return enoughSize
-        }) 
-        rings.forEach(ring=>{
-            if(ring.closetChilds){
-                ring.closetChilds = ring.closetChilds.filter(e=>rings.includes(e))
-            }
-        })
-        
-        return rings
-        
-    })  */ //在dealRings前不能随意删除rings,因为判断是否是最小环时需要全部的环  
-    
-    rings.forEach(ring=>{ //这里和cad中的不太一样, cad中双数个parent算外环,单数内环; 这里不分内外, 只看有无parent child
-        if(ring.parent.length){
-            ring.closetParent = ring.parent.find(ring_ => ring_.parent.length == ring.parent.length - 1)//最近一层的大环就是比它的parent个数少一的
-            ring.closetParent.closetChilds || (ring.closetParent.closetChilds = [])//内环可能多个
-            ring.closetParent.closetChilds.push(ring)
-        } 
-    })
-    
-    
-    
-    //console.log(rings)
-    
-    
-    
-   
-    
-    var _ring = rings.map(ring=>{ 
-        var data = {
-            id: ring.id,  
-            points: ring.points.map(point=>{return {id: point.ids[0], x:point.x, y:point.y}}),
-            /* doors : o.doors.filter(door=>{
-                if(ring.closetChilds){
-                    var childOutLines = getDifferenceSetMuti(ring.closetChilds.map(ring=>ring.lines)) //最近子环的外边
-                    return ring.lines.concat(childOutLines).includes(door.atLine)   
-                }else{
-                    return ring.lines.includes(door.atLine) 
-                } 
-            }), */ 
-            area:ring.area,
-            closetParent : ring.closetParent && ring.closetParent.id,
-            closetChilds : ring.closetChilds && ring.closetChilds.map(e=>e.id) 
-        } 
-        
-        return data
-    })
-        
-    //console.log(JSON.stringify(_ring))
-
-    return _ring
-    
-    
-    
-    
-    
-}
-
- 
-export default searchRings

+ 0 - 486
src/utils/transitions.js

@@ -1,486 +0,0 @@
- 
-var easing = {};
-//渐变曲线函数,反应加速度的变化
-
-
-//currentTime:x轴当前时间(从0-到duration), startY:起始点, duration:总时长, wholeY:路程 (即endY-startY)
-//参数基本是 x, 0, 1, 1 
-
-
-/* 
-easeOut 基本是y= m * (x-dur)^k + n, 若k为偶数,m<0, 若k为奇数,m>0;  (因为偶数的话必须开口向下才能获得斜率递减的递增的那段,而奇数是对称的,单调递增. )
-根据x=0时y=0, x=dur时y=S , 得 n = S,m = -S/(-dur)^k
-
-*/
- 
-easing.getEaseOut = function(k){// k 是>=2的整数. 越大变化率越大, 相同初始速度所需要时间越久 
-    let easeFun
-    k = Math.round(k)
-     
-    if(k<2){   
-        k = Math.PI / 2  
-        easeFun = easing.easeOutSine  
-    }else{
-        easeFun = function(currentTime, startY, wholeY, duration) {  
-            if(k>2){ 
-                console.log(k) 
-            }
-           return -wholeY/Math.pow(-duration, k) * Math.pow(currentTime-duration,  k) + wholeY 
-        }  
-    }
-      
-    return {
-        k,
-        easeFun  
-    }  
-}
-
-
-
-
-
-
-
-
-
-
-easing.linearTween = function(currentTime, startY, wholeY, duration) {
-    return wholeY * currentTime / duration + startY
-}
-,
-easing.easeInQuad = function(currentTime, startY, wholeY, duration) {
-    return currentTime /= duration,
-    wholeY * currentTime * currentTime + startY
-}
-,
-easing.easeOutQuad = function(currentTime, startY, wholeY, duration) { // 如套上实际的距离S和时长dur, y = - S / dur *(x^2-2x) 当s为1,dur为1时,是  y = -(x-1)^2 + 1 , 在0-1中是斜率递减的递增函数.     导数- S / dur *(2x-2 )   可求出实时速度  故在0这一时刻,速度为 2S/dur  
-    return currentTime /= duration,
-    -wholeY * currentTime * (currentTime - 2) + startY
-}
-,
-easing.easeInOutQuad = function(currentTime, startY, wholeY, duration) {
-    return currentTime /= duration / 2,
-    currentTime < 1 ? wholeY / 2 * currentTime * currentTime + startY : (currentTime--,
-    -wholeY / 2 * (currentTime * (currentTime - 2) - 1) + startY)
-}
-,
-easing.easeInCubic = function(currentTime, startY, wholeY, duration) {
-    return currentTime /= duration,
-    wholeY * currentTime * currentTime * currentTime + startY
-}
-,
-easing.easeOutCubic = function(currentTime, startY, wholeY, duration) {// y = S / dur^3 *(x-dur)^3 + S,对称中心是(dur,S),从0-dur是 斜率递减的递增函数,导数为3S/dur^3 * (x-dur)^2, 0时速度为3S/dur
-    return currentTime /= duration,
-    currentTime--,
-    wholeY * (currentTime * currentTime * currentTime + 1) + startY
-}
-,
-easing.easeInOutCubic = function(currentTime, startY, wholeY, duration) {
-    return currentTime /= duration / 2,
-    currentTime < 1 ? wholeY / 2 * currentTime * currentTime * currentTime + startY : (currentTime -= 2,
-    wholeY / 2 * (currentTime * currentTime * currentTime + 2) + startY)
-}
-,
-easing.easeInQuart = function(currentTime, startY, wholeY, duration) {
-    return currentTime /= duration,
-    wholeY * currentTime * currentTime * currentTime * currentTime + startY
-}
-,
-easing.easeOutQuart = function(currentTime, startY, wholeY, duration) {//根据上面的计算,估计0时速度应该是4S/dur吧…… 
-    return currentTime /= duration,
-    currentTime--,
-    -wholeY * (currentTime * currentTime * currentTime * currentTime - 1) + startY
-}
-,
-easing.easeInOutQuart = function(currentTime, startY, wholeY, duration) {
-    return currentTime /= duration / 2,
-    currentTime < 1 ? wholeY / 2 * currentTime * currentTime * currentTime * currentTime + startY : (currentTime -= 2,
-    -wholeY / 2 * (currentTime * currentTime * currentTime * currentTime - 2) + startY)
-}
-,
-easing.easeInQuint = function(currentTime, startY, wholeY, duration) {
-    return currentTime /= duration,
-    wholeY * currentTime * currentTime * currentTime * currentTime * currentTime + startY
-}
-,
-easing.easeOutQuint = function(currentTime, startY, wholeY, duration) {
-    return currentTime /= duration,
-    currentTime--,
-    wholeY * (currentTime * currentTime * currentTime * currentTime * currentTime + 1) + startY
-}
-,
-easing.easeInOutQuint = function(currentTime, startY, wholeY, duration) {
-    return currentTime /= duration / 2,
-    currentTime < 1 ? wholeY / 2 * currentTime * currentTime * currentTime * currentTime * currentTime + startY : (currentTime -= 2,
-    wholeY / 2 * (currentTime * currentTime * currentTime * currentTime * currentTime + 2) + startY)
-}
-,
-easing.easeInSine = function(currentTime, startY, wholeY, duration) {
-    return -wholeY * Math.cos(currentTime / duration * (Math.PI / 2)) + wholeY + startY
-}
-,
-easing.easeOutSine = function(currentTime, startY, wholeY, duration) {// y' = S * PI / 2 / dur * cos(PI/2/dur * x)
-    console.log('easeOutSine')
-    return wholeY * Math.sin(currentTime / duration * (Math.PI / 2)) + startY
-}
-,
-easing.easeInOutSine = function(currentTime, startY, wholeY, duration) {
-    return -wholeY / 2 * (Math.cos(Math.PI * currentTime / duration) - 1) + startY
-}
-,
-easing.easeInExpo = function(currentTime, startY, wholeY, duration) {
-    return wholeY * Math.pow(2, 10 * (currentTime / duration - 1)) + startY
-}
-,
-easing.easeOutExpo = function(currentTime, startY, wholeY, duration) {
-    return wholeY * (-Math.pow(2, -10 * currentTime / duration) + 1) + startY
-}
-,
-easing.easeInOutExpo = function(currentTime, startY, wholeY, duration) {
-    return currentTime /= duration / 2,
-    currentTime < 1 ? wholeY / 2 * Math.pow(2, 10 * (currentTime - 1)) + startY : (currentTime--,
-    wholeY / 2 * (-Math.pow(2, -10 * currentTime) + 2) + startY)
-}
-,
-easing.easeInCirc = function(currentTime, startY, wholeY, duration) {
-    return currentTime /= duration,
-    -wholeY * (Math.sqrt(1 - currentTime * currentTime) - 1) + startY
-}
-,
-easing.easeOutCirc = function(currentTime, startY, wholeY, duration) {
-    return currentTime /= duration,
-    currentTime--,
-    wholeY * Math.sqrt(1 - currentTime * currentTime) + startY
-}
-,
-easing.easeInOutCirc = function(currentTime, startY, wholeY, duration) {
-    return currentTime /= duration / 2,
-    currentTime < 1 ? -wholeY / 2 * (Math.sqrt(1 - currentTime * currentTime) - 1) + startY : (currentTime -= 2,
-    wholeY / 2 * (Math.sqrt(1 - currentTime * currentTime) + 1) + startY)
-}
-,
-easing.easeInElastic = function(currentTime, startY, wholeY, duration) {
-    var r = 1.70158
-      , o = 0
-      , a = wholeY;
-    return 0 === currentTime ? startY : 1 === (currentTime /= duration) ? startY + wholeY : (o || (o = .3 * duration),
-    a < Math.abs(wholeY) ? (a = wholeY,
-    r = o / 4) : r = o / (2 * Math.PI) * Math.asin(wholeY / a),
-    -(a * Math.pow(2, 10 * (currentTime -= 1)) * Math.sin((currentTime * duration - r) * (2 * Math.PI) / o)) + startY)
-}
-,
-easing.easeOutElastic = function(currentTime, startY, wholeY, duration) {
-    var r = 1.70158
-      , o = 0
-      , a = wholeY;
-    return 0 === currentTime ? startY : 1 === (currentTime /= duration) ? startY + wholeY : (o || (o = .3 * duration),
-    a < Math.abs(wholeY) ? (a = wholeY,
-    r = o / 4) : r = o / (2 * Math.PI) * Math.asin(wholeY / a),
-    a * Math.pow(2, -10 * currentTime) * Math.sin((currentTime * duration - r) * (2 * Math.PI) / o) + wholeY + startY)
-}
-,
-easing.easeInOutElastic = function(currentTime, startY, wholeY, duration) {
-    var r = 1.70158
-      , o = 0
-      , a = wholeY;
-    return 0 === currentTime ? startY : 2 === (currentTime /= duration / 2) ? startY + wholeY : (o || (o = duration * (.3 * 1.5)),
-    a < Math.abs(wholeY) ? (a = wholeY,
-    r = o / 4) : r = o / (2 * Math.PI) * Math.asin(wholeY / a),
-    currentTime < 1 ? -.5 * (a * Math.pow(2, 10 * (currentTime -= 1)) * Math.sin((currentTime * duration - r) * (2 * Math.PI) / o)) + startY : a * Math.pow(2, -10 * (currentTime -= 1)) * Math.sin((currentTime * duration - r) * (2 * Math.PI) / o) * .5 + wholeY + startY)
-}
-,
-easing.easeInBack = function(currentTime, startY, wholeY, duration, r) {
-    return void 0 === r && (r = 1.70158),
-    wholeY * (currentTime /= duration) * currentTime * ((r + 1) * currentTime - r) + startY
-}
-,
-easing.easeOutBack = function(currentTime, startY, wholeY, duration, r) {
-    return void 0 === r && (r = 1.70158),
-    wholeY * ((currentTime = currentTime / duration - 1) * currentTime * ((r + 1) * currentTime + r) + 1) + startY
-}
-,
-easing.easeInOutBack = function(currentTime, startY, wholeY, duration, r) {
-    return void 0 === r && (r = 1.70158),
-    (currentTime /= duration / 2) < 1 ? wholeY / 2 * (currentTime * currentTime * (((r *= 1.525) + 1) * currentTime - r)) + startY : wholeY / 2 * ((currentTime -= 2) * currentTime * (((r *= 1.525) + 1) * currentTime + r) + 2) + startY
-}
-,
-easing.easeOutBounce = function(currentTime, startY, wholeY, duration) {
-    return (currentTime /= duration) < 1 / 2.75 ? wholeY * (7.5625 * currentTime * currentTime) + startY : currentTime < 2 / 2.75 ? wholeY * (7.5625 * (currentTime -= 1.5 / 2.75) * currentTime + .75) + startY : currentTime < 2.5 / 2.75 ? wholeY * (7.5625 * (currentTime -= 2.25 / 2.75) * currentTime + .9375) + startY : wholeY * (7.5625 * (currentTime -= 2.625 / 2.75) * currentTime + .984375) + startY
-}
-,
-easing.easeInBounce = function(currentTime, startY, wholeY, r) {
-    return wholeY - easing.easeOutBounce(r - currentTime, 0, wholeY, r) + startY
-}
-,
-easing.easeInOutBounce = function(currentTime, startY, wholeY, r) {
-    return currentTime < r / 2 ? .5 * easing.easeInBounce(2 * currentTime, 0, wholeY, r) + startY : .5 * easing.easeOutBounce(x, 2 * currentTime - r, 0, wholeY, r) + .5 * wholeY + startY
-}
-
- 
-
-
-
-
-
-
-
-
-
-
-
-
-var lerp = {
-	/* vector: function(currentTime, startY, f) {//xzw change, add f
-		var wholeY = currentTime.clone();
-		return startY = startY.clone(),
-		function(duration) {
-			currentTime.set(wholeY.x * (1 - duration) + startY.x * duration, wholeY.y * (1 - duration) + startY.y * duration, wholeY.z * (1 - duration) + startY.z * duration)
-			f && f(currentTime,duration);
-		}
-	},
-    quaternion: function(currentTime, startY, f) {//xzw change, add f
-        var wholeY = currentTime.clone();
-        return function(duration) {
-            currentTime.copy(wholeY).slerp(startY, duration);
-			f && f(currentTime,duration);
-        }
-    },
-    property: function(currentTime, startY, wholeY, duration) {
-        var r = currentTime[startY];
-        return function(o) {
-            currentTime[startY] = r * (1 - o) + wholeY * o,
-            duration && duration(currentTime[startY])
-        }
-    },
-    uniform: function(currentTime, startY, wholeY) {
-        var duration = currentTime.material.uniforms[startY].value;
-        return function(r) {
-            try{
-                currentTime.material.uniforms[startY] && (currentTime.material.uniforms[startY].value = duration * (1 - r) + wholeY * r)
-            }catch(currentTime){
-                console.log(1)
-            }
-            
-        }
-    },
-    matrix4: function(currentTime, startY) {
-        var wholeY = currentTime.clone();
-        return function(duration) {
-            for (var r = currentTime.elements, o = wholeY.elements, a = startY.elements, s = 0; s < 16; s++)
-                r[s] = o[s] * (1 - duration) + a[s] * duration
-        }
-    },
-    allUniforms: function(currentTime, startY, wholeY) {
-        var duration = currentTime.map(function(currentTime) {
-            return this.uniform(currentTime, startY, wholeY)
-        }
-        .bind(this));
-        return function(currentTime) {
-            duration.forEach(function(startY) {
-                startY(currentTime)
-            })
-        }
-    } */
-    
-    
-    
-    vector: function(t, i, f) {//xzw change, add f
-        var n = t.clone();
-        return i = i.clone(),
-        function(e) {
-            t.set(n.x * (1 - e) + i.x * e, n.y * (1 - e) + i.y * e, n.z * (1 - e) + i.z * e)
-            f && f(t,e);
-        }
-    },
-    quaternion: function(t, i, f) {//xzw change, add f
-        var n = t.clone();
-        return function(e) {
-            t.copy(n).slerp(i, e)
-            f && f(t,e);
-        }
-    },
-    property: function(t, i, n, r) {
-        var o = t[i];
-        return function(e) {
-            t[i] = o * (1 - e) + n * e,
-            r && r(t[i])     
-        }
-    },
-    uniform: function(t, i, n) {
-        var r = t.material.uniforms[i].value;
-        return function(e) {
-            t.material.uniforms[i] && (t.material.uniforms[i].value = r * (1 - e) + n * e)
-        }
-    },
-    matrix4: function(o, a) {
-        var s = o.clone();
-        return function(e) {
-            for (var t = o.elements, i = s.elements, n = a.elements, r = 0; r < 16; r++)
-                t[r] = i[r] * (1 - e) + n[r] * e
-        }
-    },
-    allUniforms: function(e, t, i) {
-        var n = e.map(function(e) {
-            return this.uniform(e, t, i)
-        }
-        .bind(this));
-        return function(t) {
-            n.forEach(function(e) {
-                e(t)
-            })
-        }
-    }
-};
- 
-
-
-
-
-/* 
-    渐变
-    
-
- */
-
-var transitions = {
-    globalDone: null,
-    funcs: [],
-    counter: 0,
-    uniqueID: 0,
-    start: function(func, duration, done, delay, ease, name, id, cancelFun) {
-        return delay = delay || 0,
-        this.funcs.push({
-            func: func,
-            current: -delay * Math.abs(duration),                      //当前时间
-            duration: (1 - Math.max(delay, 0)) * Math.abs(duration),   //总时长
-            done: done,
-            easing: ease || easing.linearTween,                //渐变曲线
-            cycling: duration < 0,
-            running: !0,
-            debug: delay < 0,
-            name: name || "T" + this.counter,
-            id: void 0 === id ? this.counter : id,
-            paused: !1,
-			cancelFun : cancelFun,   //取消时执行的函数
-        }),
-        func(0, 16),
-        this.counter += 1,
-        func
-    },
-    trigger: function(e) {
-        var t = void 0 === e.delayRatio ? 0 : e.delayRatio
-            , u = e.func || function() {}
-            , r = void 0 === e.duration ? 0 : e.duration;
-        void 0 !== e.cycling && e.cycling && (r = -Math.abs(r));
-        var o = e.done || null
-            , a = e.easing || easing.linearTween
-            , s = e.name || "R" + this.counter
-            , l = void 0 === e.id ? this.counter : e.id;
-        return this.start(u, r, o, t, a, s, l)
-    },
-    setTimeout: function(e, t, u) {
-        var duration = void 0 === u ? this.counter : u;
-        return this.trigger({
-            done: e,
-            duration: void 0 === t ? 0 : t,
-            name: "O" + this.counter,
-            id: duration
-        })
-    },
-    pause: function() {
-        this.paused = !0
-    },
-    resume: function() {
-        this.paused = !1
-    },
-    update: function(e) {
-        this.funcs.forEach(function(t) {
-            if (!(t.paused || (t.current += 1e3 * e,
-            t.current < 0)))
-                if (t.current >= t.duration && !t.cycling) {
-                    var u = t.easing(1, 0, 1, 1);
-                    t.func(u, 1e3 * e),
-                    t.done && t.done(),
-                    t.running = !1
-                } else {
-                    var duration = t.easing(t.current % t.duration / t.duration, 0, 1, 1)
-                        , r = t.func(duration, 1e3 * e) || !1;
-                    r && (t.done && t.done(),
-                    t.running = !1)
-                }
-        });
-        var t = this.funcs.length;
-        this.funcs = this.funcs.filter(function(e) {
-            return e.running
-        });
-        var u = this.funcs.length;
-        if (t > 0 && 0 === u && this.globalDone) {
-            var duration = this.globalDone;
-            this.globalDone = null,
-            duration()
-        }
-    },
-    adjustSpeed: function(e, t) {
-        for (var u = this.getById(e), duration = 0; duration < u.length; duration++) {
-            var r = u[duration];
-            r.duration /= t,
-            r.current /= t
-        }
-    },
-    getById: function(e) {
-        return this.funcs.filter(function(t) {
-            return e === t.id
-        })
-    },
-    get: function(e) {
-        for (var t = 0; t < this.funcs.length; t += 1)
-            if (this.funcs[t].func === e)
-                return this.funcs[t];
-        return null
-    },
-    isRunning: function(e) {
-        var t = this.get(e);
-        return null !== t && t.running
-    },
-    countActive: function() {
-        for (var e = 0, t = 0; t < this.funcs.length; t += 1)
-            e += this.funcs[t].running;
-        return e
-    },
-    listActive: function() {
-        for (var e = [], t = 0; t < this.funcs.length; t += 1)
-            this.funcs[t].running && e.push(this.funcs[t].name);
-        return e
-    },
-    done: function(e) {
-        this.globalDone = e
-    },
-    cancelById: function(e, dealCancelFun) { //xzw add dealDone
-        var t = void 0 === e ? 0 : e;
-		let cancels = []
-        this.funcs = this.funcs.filter(function(e) {
-			var is = e.id == t;
-			
-			if(is && dealCancelFun){
-                e.cancelFun && cancels.push(e.cancelFun)
-				//e.cancelFun && e.cancelFun()
-			} 
-            return !is
-        })
-        
-        cancels.forEach(e=>{e()}) //先从funcs中去除后再执行
-        
-        
-    },
-    cancel: function(e) {
-        this.funcs = this.funcs.filter(function(t) {
-            return t.func !== e
-        })
-    },
-    getUniqueId: function() {
-        return this.uniqueID -= 1,
-        this.uniqueID
-    } 
-};
-
-export    {transitions, lerp, easing}

+ 28 - 14
src/viewer/LoadProject.js

@@ -1,7 +1,7 @@
 
 import * as THREE from "../../libs/three.js/build/three.module.js";
 import {Annotation} from "../Annotation.js";
-import {Measure} from "../objects/tool/Measure.js";
+import {Measure} from "../utils/Measure.js";
 import {CameraAnimation} from "../modules/CameraAnimation/CameraAnimation.js";
 import {Utils} from "../utils.js";
 import {PointSizeType} from "../defines.js";
@@ -88,12 +88,29 @@ function loadMeasurement(viewer, data){
 	if(duplicate){
 		return;
 	}
-    
-    data.points = data.points.map(point=>new THREE.Vector3(...point))
-    
-	const measure = viewer.measuringTool.createMeasureFromData(data)
 
-	 
+	const measure = new Measure();
+
+	measure.uuid = data.uuid;
+	measure.name = data.name;
+	measure.showDistances = data.showDistances;
+	measure.showCoordinates = data.showCoordinates;
+	measure.showArea = data.showArea;
+	measure.closed = data.closed;
+	measure.showAngles = data.showAngles;
+	measure.showHeight = data.showHeight;
+	measure.showCircle = data.showCircle;
+	measure.showAzimuth = data.showAzimuth;
+	measure.showEdges = data.showEdges;
+	// color
+
+	for(const point of data.points){
+		const pos = new THREE.Vector3(...point);
+		measure.addMarker(pos);
+	}
+
+	viewer.scene.addMeasurement(measure);
+
 }
 
 function loadVolume(viewer, data){
@@ -297,7 +314,7 @@ function loadClassification(viewer, data){
 	viewer.setClassifications(classifications);
 }
 
-export async function loadProject(viewer, data, done){
+export async function loadProject(viewer, data){
 
 	if(data.type !== "Potree"){
 		console.error("not a valid Potree project");
@@ -308,11 +325,11 @@ export async function loadProject(viewer, data, done){
 
 	loadView(viewer, data.view);
 
-	/* const pointcloudPromises = [];
+	const pointcloudPromises = [];
 	for(const pointcloud of data.pointclouds){
 		const promise = loadPointCloud(viewer, pointcloud);
 		pointcloudPromises.push(promise);
-	} */
+	}
 
 	for(const measure of data.measurements){
 		loadMeasurement(viewer, measure);
@@ -340,13 +357,10 @@ export async function loadProject(viewer, data, done){
 
 	loadClassification(viewer, data.classification);
 
-    done && done()
-
-
 	// need to load at least one point cloud that defines the scene projection,
 	// before we can load stuff in other projections such as geopackages
 	//await Promise.any(pointcloudPromises); // (not yet supported)
-	/* Utils.waitAny(pointcloudPromises).then( () => {
+	Utils.waitAny(pointcloudPromises).then( () => {
 		if(data.geopackages){
 			for(const geopackage of data.geopackages){
 				loadGeopackage(viewer, geopackage);
@@ -354,5 +368,5 @@ export async function loadProject(viewer, data, done){
 		}
 	});
 
-	await Promise.all(pointcloudPromises); */
+	await Promise.all(pointcloudPromises);
 }

+ 15 - 105
src/viewer/Scene.js

@@ -3,9 +3,9 @@ import * as THREE from "../../libs/three.js/build/three.module.js";
 import {Annotation} from "../Annotation.js";
 import {CameraMode} from "../defines.js";
 import {View} from "./View.js";
-import {Utils} from "../utils.js"; 
-import Axis from '../objects/Axis.js'
-import { EventDispatcher } from "../EventDispatcher.js";
+import {Utils} from "../utils.js";
+import {EventDispatcher} from "../EventDispatcher.js";
+
 
 export class Scene extends EventDispatcher{
 
@@ -15,17 +15,11 @@ export class Scene extends EventDispatcher{
 		this.annotations = new Annotation();
 		
 		this.scene = new THREE.Scene();
-        //this.sceneBG = new THREE.Scene(); //用来放skybox
-        //this.sceneOverlay = new THREE.Scene();  
-         
+		this.sceneBG = new THREE.Scene();
 		this.scenePointCloud = new THREE.Scene();
-        
-        
 
-		this.cameraP = new THREE.PerspectiveCamera(this.fov, 1, Potree.config.view.near, Potree.config.view.near);
-		this.cameraO = new THREE.OrthographicCamera(-1, 1, 1, -1, Potree.config.view.near, Potree.settings.cameraFar);
-        this.cameraP.limitFar = true//add
-        
+		this.cameraP = new THREE.PerspectiveCamera(this.fov, 1, 0.1, 1000*1000);
+		this.cameraO = new THREE.OrthographicCamera(-1, 1, 1, -1, 0.1, 1000*1000);
 		this.cameraVR = new THREE.PerspectiveCamera();
 		this.cameraBG = new THREE.Camera();
 		this.cameraScreenSpace = new THREE.OrthographicCamera(-1, 1, 1, -1, 0.1, 10);
@@ -54,18 +48,6 @@ export class Scene extends EventDispatcher{
 		this.directionalLight = null;
 
 		this.initialize();
-        
-        
-        //-------------
-        this.axisArrow = new Axis();
-        this.scene.add(this.axisArrow)
-        if(!Potree.settings.isDebug)this.axisArrow.visible = false
-        viewer.setObjectLayers(this.axisArrow,  'bothMapAndScene' )
-        
-        
-        this.tags = new THREE.Object3D;
-        this.scene.add(this.tags)
-
 	}
 
 	estimateHeightAt (position) {
@@ -148,20 +130,6 @@ export class Scene extends EventDispatcher{
 		});
 	}
 
-    //add:
-    removePointCloud (pointcloud) {
-        let index = this.pointclouds.indexOf(pointcloud);
-        if(index == -1)return
-        this.pointclouds.splice(index, 1)
-        this.scenePointCloud.remove(pointcloud);
-      
-        pointcloud.panos.forEach(pano=>{ 
-            pano.dispose()  
-        })
-        
-        
-    }
-    
 	addVolume (volume) {
 		this.volumes.push(volume);
 		this.dispatchEvent({
@@ -198,9 +166,7 @@ export class Scene extends EventDispatcher{
 	add360Images(images){
 		this.images360.push(images);
 		this.scene.add(images.node);
-        //this.sceneOverlay.add(images.node);//add
-        
-        
+
 		this.dispatchEvent({
 			'type': '360_images_added',
 			'scene': this,
@@ -268,7 +234,7 @@ export class Scene extends EventDispatcher{
 	};
 
 	removeCameraAnimation(animation){
-		let index = this.cameraAnimations.indexOf(animation);
+		let index = this.cameraAnimations.indexOf(volume);
 		if (index > -1) {
 			this.cameraAnimations.splice(index, 1);
 
@@ -371,10 +337,7 @@ export class Scene extends EventDispatcher{
 	}
 
 	getActiveCamera() {
-        return viewer.mainViewport.camera
-        
-        
-        
+
 		if(this.overrideCamera){
 			return this.overrideCamera;
 		}
@@ -396,19 +359,10 @@ export class Scene extends EventDispatcher{
 		this.referenceFrame.matrixAutoUpdate = false;
 		this.scenePointCloud.add(this.referenceFrame);
 
-
-        if(window.axisYup){
-            
-
-        }else{
-            this.cameraP.up.set(0, 0, 1);
-            this.cameraO.up.set(0, 0, 1);
-            
-
-        }
-        this.cameraP.position.set(1000, 1000, 1000);
-        this.cameraO.position.set(1000, 1000, 1000);
-
+		this.cameraP.up.set(0, 0, 1);
+		this.cameraP.position.set(1000, 1000, 1000);
+		this.cameraO.up.set(0, 0, 1);
+		this.cameraO.position.set(1000, 1000, 1000);
 		//this.camera.rotation.y = -Math.PI / 4;
 		//this.camera.rotation.x = -Math.PI / 6;
 		this.cameraScreenSpace.lookAt(new THREE.Vector3(0, 0, 0), new THREE.Vector3(0, 0, -1), new THREE.Vector3(0, 1, 0));
@@ -418,21 +372,8 @@ export class Scene extends EventDispatcher{
 		this.directionalLight.lookAt( new THREE.Vector3(0, 0, 0));
 		this.scenePointCloud.add( this.directionalLight );
 		
-		let light = new THREE.AmbientLight( 0x555555 ); // soft white light 
+		let light = new THREE.AmbientLight( 0x555555 ); // soft white light
 		this.scenePointCloud.add( light );
-        
-         
-        
-        //add:------给空间模型的box 或其他obj------
-        let light2 = new THREE.AmbientLight( 16777215, 1 );
-        viewer.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')
-        this.scene.add(light3)  
-        //--------------------------------------------
 
 		{ // background
 			let texture = Utils.createBackgroundTexture(512, 512);
@@ -447,30 +388,9 @@ export class Scene extends EventDispatcher{
 			);
 			bg.material.depthTest = false;
 			bg.material.depthWrite = false;
-            bg.name = 'bg'
-			//this.sceneBG.add(bg);
-            this.scene.add(bg)
-            bg.layers.set(Potree.config.renderLayers.bg)
-            
+			this.sceneBG.add(bg);
 		}
 
-        { // background color
-			  
-			let bg2 = new THREE.Mesh(
-				new THREE.PlaneBufferGeometry(2, 2, 1),
-				new THREE.MeshBasicMaterial({
-					transparent : true
-				})
-			);
-			bg2.material.depthTest = false;
-			bg2.material.depthWrite = false;
-            bg2.name = 'bg2' 
-            this.scene.add(bg2)
-            bg2.layers.set(Potree.config.renderLayers.bg2) 
-            this.bg2 = bg2
-		}
-
-
 		// { // lights
 		// 	{
 		// 		let light = new THREE.DirectionalLight(0xffffff);
@@ -495,16 +415,6 @@ export class Scene extends EventDispatcher{
 		// }
 	}
 	
-    /* switchBg(type){//add
-        let bg,;
-        if(type == 'gradient'){
-            bg
-        }else if(type == 'overlayColor'){
-            
-        }
-    } */
-    
-    
 	addAnnotation(position, args = {}){		
 		if(position instanceof Array){
 			args.position = new THREE.Vector3().fromArray(position);

+ 0 - 91
src/viewer/Viewport.js

@@ -1,91 +0,0 @@
-
-
-
-import * as THREE from "../../libs/three.js/build/three.module.js";
-import Common from '../utils/Common.js'
-
-export default class Viewport{
-    
-    constructor( view, camera, prop={}){//目前不支持换camera
-        
-        this.left = prop.left;
-        this.bottom = prop.bottom;
-        this.width = prop.width;
-        this.height = prop.height;
-        this.name = prop.name 
-        this.view = view
-        this.camera = camera 
-        this.active = true 
-        this.unableChangePos = false
-        this.noPointcloud;
-        //this.keys = [...] firstPersonCtl....
-        this.resolution = new THREE.Vector2;
-        this.resolution2 = new THREE.Vector2;
-        this.offset = new THREE.Vector2; //viewportOffset 范围从0-整个画布的像素
-        this.extraEnableLayers = prop.extraEnableLayers || [];//额外可展示的层
-        this.cameraLayers = prop.cameraLayers 
-        this.pixelRatio = prop.pixelRatio  //如果规定pixelRatio的话要传,这样就覆盖devicePicelRatio, 如magnifier
-    }
-     
-    
-    clone(){ 
-        return Common.CloneClassObject(this)
-          
-    }
-    
-    getMoveSpeed(){
-        return this.moveSpeed
-    }
-    setMoveSpeed(e){
-        this.moveSpeed = e
-    }
-    
-    layersAdd(name){
-        this.extraEnableLayers.includes(name) || this.extraEnableLayers.push(name)
-        
-    }
-    layersRemove(name){
-        let index = this.extraEnableLayers.indexOf(name)
-        if(index > -1){
-            this.extraEnableLayers.splice(index, 1)
-        }
-    }
-
-
-    
-	cameraChanged() {
-		var copy = ()=>{
-            this.previousState = {
-                projectionMatrix: this.camera.projectionMatrix.clone(),//worldMatrix在this.control时归零了所以不用了吧,用position和qua也一样
-                position: this.camera.position.clone(),
-                quaternion: this.camera.quaternion.clone()
-                
-            }; 
-        }
-        let projectionChanged = true
-        let positionChanged = true
-        let quaternionChanged = true
-        let getChanged = ()=>{
-            return {
-                projectionChanged,positionChanged,quaternionChanged, 
-                changed:projectionChanged || positionChanged || quaternionChanged
-            }
-        }
-        if (this.previousState){ 
-            projectionChanged = !this.camera.projectionMatrix.equals(this.previousState.projectionMatrix) 
-            positionChanged = !this.camera.position.equals(this.previousState.position)  
-            quaternionChanged = !this.camera.quaternion.equals(this.previousState.quaternion) 
-        }   
-        copy() 
-        
-        return getChanged()
-	}
-    
-    setResolution(w,h, wholeW=0, wholeH=0){
-        this.resolution.set(w,h);//是client的width height
-        
-        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) 
-    }
-}

+ 0 - 353
src/viewer/viewerBase.js

@@ -1,353 +0,0 @@
-
-import * as THREE from "../../libs/three.js/build/three.module.js"; 
-
-import Common from '../utils/Common.js'
-import { ExtendEventDispatcher } from "../custom/ExtendEventDispatcher.js";
-
-export class ViewerBase extends ExtendEventDispatcher{
-    constructor(domElement, args = {}){
-        super()
-        this.name = args.name
-        this.renderArea = domElement 
-        this.oldResolution = new THREE.Vector2()
-        
-        this.screenSizeInfo = {
-            W:0, H:0, pixelRatio:1 , windowWidth:0, windowHeight:0
-        }
-        
-        this.initContext(args);
-        
-         
-        this.addEventListener('content_changed', ()=>{//画面改变,需要渲染
-            this.needRender = true
-        })
-        
-        
-    }
-    
-    
-    
-    
-    
-    initContext(args){
-        //console.log(`initializing three.js ${THREE.REVISION}`);
-
-        let width = this.renderArea.clientWidth;
-        let height = this.renderArea.clientHeight;
-
-        let contextAttributes = {
-            alpha: true,
-            depth: true,
-            stencil: false,
-            antialias: true, 
-            preserveDrawingBuffer: true,
-            powerPreference: "high-performance",
-        }; 
-
-        let canvas = document.createElement("canvas");
-
-        let context = canvas.getContext('webgl', contextAttributes );
-
-        this.renderer = new THREE.WebGLRenderer({
-            alpha: true, //支持透明
-            premultipliedAlpha: false, 
-            canvas: canvas,
-            context: context, 
-        }); 
-        
-        this.renderer.sortObjects = true; //原先false 打开了renderOrder才奏效
-        //this.renderer.setSize(width, height);
-        this.renderer.autoClear = args.autoClear || false;
-
-
-        //args.clearColor = args.clearColor || '#aa0033'
-        args.clearColor && this.renderer.setClearColor(args.clearColor)
-        this.renderArea.appendChild(this.renderer.domElement);
-        this.renderer.domElement.tabIndex = '2222';
-        this.renderer.domElement.style.position = 'absolute';
-        this.renderer.domElement.addEventListener('mousedown', () => {
-            this.renderer.domElement.focus();
-        });
-        //this.renderer.domElement.focus();
-
-        // NOTE: If extension errors occur, pass the string into this.renderer.extensions.get(x) before enabling
-        // enable frag_depth extension for the interpolation shader, if available
-        let gl = this.renderer.getContext();
-        
-         
-        gl.getExtension('EXT_frag_depth');
-        gl.getExtension('WEBGL_depth_texture');
-        gl.getExtension('WEBGL_color_buffer_float'); 	// Enable explicitly for more portability, EXT_color_buffer_float is the proper name in WebGL 2
-        
-        if(gl.createVertexArray == null){
-            let extVAO = gl.getExtension('OES_vertex_array_object');
-
-            if(!extVAO){
-                throw new Error("OES_vertex_array_object extension not supported");
-            }
-
-            gl.createVertexArray = extVAO.createVertexArrayOES.bind(extVAO);
-            gl.bindVertexArray = extVAO.bindVertexArrayOES.bind(extVAO);
-        }
-
- 
-       /*  let oldClear = gl.clear; 
-        gl.clear = (bits)=>{
-             console.error('clear')
-        }   
- */
-        
-    }
-    
-    
-    
-    
-    updateScreenSize(o={}) { //有可能需要让viewport来判断,当窗口大小不变但viewport大小变时 
-           
-        var render = false, ratio, w, h;
-        //记录应当render的大小
-        if (o.width != void 0 && o.height != void 0) {
-            w = o.width
-            h = o.height
-            render = true
-            ratio = 1
-        }else { 
-
-            w = this.renderArea.clientWidth;
-            h = this.renderArea.clientHeight
-            
-
-             
-            if(w !== this.screenSizeInfo.W || h !== this.screenSizeInfo.H || o.forceUpdateSize || this.screenSizeInfo.pixelRatio != window.devicePixelRatio){
-                this.screenSizeInfo.W = w 
-                this.screenSizeInfo.H = h 
-                render = true 
-                this.screenSizeInfo.pixelRatio = window.devicePixelRatio  //如果player放在小窗口了,也要监测devicePixelRatio,因为缩放时client宽高不会改变
-                //config.isMobile ? (ratio = Math.min(window.devicePixelRatio, 2)) : (ratio = window.devicePixelRatio)
-                ratio = window.devicePixelRatio
-            }     
-        }
-        if (render) { 
-            this.setSize(w, h, ratio); 
-        } 
-    }   
-
-
-    /* updateScreenSize(o={}) { //容易出错。。
-           
-        var render = false, ratio, w, h;
-        //记录应当render的大小
-        if (o.width != void 0 && o.height != void 0) {
-            w = o.width
-            h = o.height
-            render = true
-            ratio = 1
-        }else { 
-            w = this.renderArea.clientWidth;
-            h = this.renderArea.clientHeight 
-
-            let refreshWin = ()=>{
-                this.screenSizeInfo.windowWidth = window.innerWidth
-                this.screenSizeInfo.windowHeight = window.innerHeight
-            }
- 
-            let prepareToRender = ()=>{
-                w = this.renderArea.clientWidth;
-                h = this.renderArea.clientHeight
-                this.screenSizeInfo.W = w 
-                this.screenSizeInfo.H = h 
-                refreshWin() //render后才refreshWin
-                render = true   
-                this.screenSizeInfo.pixelRatio = window.devicePixelRatio  //如果player放在小窗口了,也要监测devicePixelRatio,因为缩放时client宽高不会改变
-                //config.isMobile ? (ratio = Math.min(window.devicePixelRatio, 2)) : (ratio = window.devicePixelRatio)
-                ratio = window.devicePixelRatio
-                //console.log('setSize11', w) 
-                o.forceUpdateSize = false ;//防止再次render
-            }
-
-            let ifNeedUpdate = ()=>{
-                w = this.renderArea.clientWidth;
-                h = this.renderArea.clientHeight
-                return o.forceUpdateSize || w !== this.screenSizeInfo.W || h !== this.screenSizeInfo.H || this.screenSizeInfo.pixelRatio != window.devicePixelRatio
-            }
-            
-            if(ifNeedUpdate()){
-                //当只有一个有效viewport时,且因为改变整个窗口大小而触发的话,延时
-                let canInterval = !o.forceUpdateSize && this.viewports.filter(e=>e.active).length==1 && (this.screenSizeInfo.windowWidth != window.innerWidth || this.screenSizeInfo.windowHeight != window.innerHeight  ) 
-                  
-                if(canInterval){
-                    Common.intervalTool.isWaiting('updateScreenSize', ()=>{ //延时update,防止崩溃 , 未到时间就拦截(第一次直接执行)
-                         if(ifNeedUpdate()){
-                            prepareToRender()
-                            return true
-                         }
-                    }, 500) 
-                }else{  
-                    //console.log('soon', window.innerWidth, this.screenSizeInfo.windowWidth)
-                    prepareToRender() 
-                } 
-                 
-            }    
-            
-        }
-        if (render) { 
-            this.setSize(w, h, ratio); 
-        } 
-    }  */
-
-     
-    setSize(width, height, devicePixelRatio, onlyForTarget){ 
-        //console.log('setSize', width) 
-        if(!onlyForTarget){//onlyForTarget表示不更改当前renderer,只是为了rendertarget才要改变viewport
-            //xst修改
-			//this.renderer.setSize(width, height, null, devicePixelRatio); // resize之后会自动clear(似乎因为setScissor ),所以一定要立刻绘制,所以setSize要在cameraChanged、update之前
-			//xst修改
-			//this.renderer.setPixelRatio (devicePixelRatio); 
-			//this.renderer.setSize(width, height); // resize之后会自动clear(似乎因为setScissor ),所以一定要立刻绘制,所以setSize要在cameraChanged、update之前
-			//xst修改
-			this.renderer.setDrawingBufferSize( width, height, devicePixelRatio )
-		}
-       
-        this.composer && this.composer.setSize(width, height);
-        
-        if(this.viewports){
-            this.viewports.forEach((view,i)=>{
-                if(!view.active)return
-                
-                var width_ = width * view.width
-                var height_ = height * view.height
-                
-                if(height_ == 0)return  //avoid NAN
-                
-                view.setResolution(Math.ceil(width_), Math.ceil(height_), width, height ) //本来应该是floor,但是这样奇数时会少一个像素,导致向左移一个像素且宽度少1。现在则多绘制1个像素,超出的1个像素应该不会绘制出来(但不知道其他地方是否有偏差,比如pick时)
-                let aspect = width_ / height_;  //camera的参数精确些,不用视口的归整的resolution像素值,否则hasChange无法为true, 导致canvasResize了但map没update从而闪烁
-                view.camera.aspect = aspect;
-                
-                if(view.camera.type == "OrthographicCamera"){
-                     
-                    /* //不改宽度 同4dkk
-                    var heightHalf = view.camera.right / aspect 
-                    view.camera.top = heightHalf 
-                    view.camera.bottom = -heightHalf  */
-                    //高宽都改 使大小不随视口大小改变  navvis (直接和视口大小一致即可,通过zoom来定大小)
-                     
-                    view.camera.left = -width_/2 
-                    view.camera.right = width_/2
-                    view.camera.bottom = -height_/2;
-                    view.camera.top = height_/2
-                    
-                    
-                }else{   
-                
-                
-                }
-                
-                view.camera.updateProjectionMatrix();
-            })
-        }
-        
-        
-        if(!onlyForTarget){//因为onlyForTarget不传递devicePixelRatio所以不发送了
-            this.emitResizeMsg({viewport:this.viewports[0],  deviceRatio:devicePixelRatio})
-        }
-         
-    } 
-    
-    emitResizeMsg(e){//切换viewport渲染时就发送一次, 通知一些材质更新resolution。  
-        if(!e.viewport.resolution.equals(this.oldResolution)){ 
-            this.dispatchEvent($.extend(e, {type:'resize'})) 
-            this.oldResolution.copy(e.viewport.resolution)
-        }
-        
-        
-    }
-    
-    
-    
-    cameraChanged() {//判断相机是否改变
-        var changed = false;
-        /* if(this.needRender){
-            this.needRender = false
-            return true
-        } */
-        for(let i=0,j=this.viewports.length;i<j;i++){
-            let changeInfo = this.viewports[i].cameraChanged()
-            if(changeInfo.changed){
-                changed = true
-                //if(!this.changeTime ||this.changeTime<100){ 
-                    this.dispatchEvent({
-                        type: "camera_changed", 
-                        camera: this.viewports[i].camera,
-                        viewport : this.viewports[i],
-                        changeInfo 
-                    }) 
-                    //this.changeTime = (this.changeTime || 0) +1
-                //} 
-            }                
-        }
-        return changed
-    }
-    
-    
-    
-    
-    
-    makeScreenshot( size,  viewports, compressRatio){//暂时不要指定viewports渲染,但也可以
-        
-       
-        let {width, height} = size;
-        
-        
-        
-        
-        /* let oldBudget = Potree.pointBudget;
-        Potree.pointBudget = Math.max(10 * 1000 * 1000, 2 * oldBudget);
-        let result = Potree.updatePointClouds(this.scene.pointclouds, camera, size );
-        Potree.pointBudget = oldBudget;
-         
-         
-		this.dispatchEvent({ //resize everything  such as lines  targets
-            type: 'resize', 
-            resolution: new THREE.Vector2(width,height), 
-        });*/
-       
-		let target = new THREE.WebGLRenderTarget(width, height, {
-			format: THREE.RGBAFormat,
-		});
- 
-	 
-		this.setSize(width, height,1,true) 
-        
-		this.render({
-            target ,
-            //camera ,
-            viewports: viewports || this.viewports,
-            screenshot : true, 
-            width ,
-            height, 
-            resize :true //需要resize
-        });
-        let dataUrl = Potree.Utils.renderTargetToDataUrl(target, width, height, this.renderer, compressRatio)
-        
-        
-		/* let pixelCount = width * height;
-		let buffer = new Uint8Array(4 * pixelCount);
-
-		this.renderer.readRenderTargetPixels(target, 0, 0, width, height, buffer);
-
-        let dataUrl = Potree.Utils.pixelsArrayToDataUrl(buffer, width, height, compressRatio) */
-
- 
-		target.dispose();
-        
-        //resize back 
-        //this.updateScreenSize({forceUpdateSize:true})   
-        
-		return {
-			width, 
-			height,
-			dataUrl 
-		};
-	}
-    
-}