Explorar o código

feat: 同步最新代码

bill %!s(int64=2) %!d(string=hai) anos
pai
achega
7377685525
Modificáronse 100 ficheiros con 4950 adicións e 15864 borrados
  1. 0 79
      examples/pano.html
  2. 0 2
      gulpfile.js
  3. 82 105
      libs/three.js/build/three.module.js
  4. 12 7
      libs/three.js/lines/Line2.js
  5. 40 22
      libs/three.js/lines/LineGeometry.js
  6. 241 560
      libs/three.js/lines/LineMaterial.js
  7. 128 274
      libs/three.js/lines/LineSegments2.js
  8. 95 76
      libs/three.js/lines/LineSegmentsGeometry.js
  9. 1 1
      libs/three.js/loaders/DDSLoader.js
  10. 170 117
      libs/three.js/loaders/DRACOLoader.js
  11. 35 92
      libs/three.js/loaders/GLTFLoader.js
  12. 499 481
      libs/three.js/loaders/KTX2Loader.js
  13. 8 9
      libs/three.js/loaders/MTLLoader.js
  14. 2 2
      libs/three.js/loaders/OBJLoader.js
  15. 0 52
      libs/three.js/loaders/draco/draco_decoder.js
  16. BIN=BIN
      libs/three.js/loaders/draco/draco_decoder.wasm
  17. 0 104
      libs/three.js/loaders/draco/draco_wasm_wrapper.js
  18. 0 21
      libs/three.js/loaders/ktx/basis_transcoder.js
  19. BIN=BIN
      libs/three.js/loaders/ktx/basis_transcoder.wasm
  20. BIN=BIN
      note/images360.updateCube笔记.jpg
  21. BIN=BIN
      resources/textures/explode.png
  22. BIN=BIN
      resources/textures/fire.png
  23. BIN=BIN
      resources/textures/icon-explode.png
  24. BIN=BIN
      resources/textures/icon-fire.png
  25. BIN=BIN
      resources/textures/icon-smoke.png
  26. BIN=BIN
      resources/textures/pic_point_s32.png
  27. BIN=BIN
      resources/textures/smokeparticle.png
  28. 3 3
      src/Actions.js
  29. 3 2
      src/Annotation.js
  30. 6 22
      src/EventDispatcher.js
  31. 0 21
      src/Features.js
  32. 1 2
      src/KeyCodes.js
  33. 1 7
      src/LRU.js
  34. 63 944
      src/PointCloudOctree.js
  35. 6 6
      src/PointCloudOctreeGeometry.js
  36. 4 3
      src/PointCloudTree.js
  37. 55 117
      src/Potree.js
  38. 16 101
      src/PotreeRenderer.js
  39. 4 10
      src/Potree_update_visibility.js
  40. 19 24
      src/objects/TextSprite.js
  41. 2 2
      src/defines.js
  42. 1 1
      src/exporter/DXFExporter.js
  43. 1 1
      src/exporter/GeoJSONExporter.js
  44. 2 19
      src/loader/BinaryLoader.js
  45. 1 1
      src/loader/GeoPackageLoader.js
  46. 2 4
      src/loader/POCLoader.js
  47. 1 1
      src/loader/ShapefileLoader.js
  48. 0 43
      src/materials/BasicMaterial.js
  49. 46 72
      src/materials/DepthBasicMaterial.js
  50. 3 4
      src/materials/EyeDomeLightingMaterial.js
  51. 0 395
      src/materials/ModelTextureMaterial.js
  52. 12 33
      src/materials/PointCloudMaterial.js
  53. 7 10
      src/materials/shaders/depthBasic.fs
  54. 12 23
      src/materials/shaders/edl.fs
  55. 1 1
      src/materials/shaders/pointcloud.fs
  56. 16 43
      src/materials/shaders/pointcloud.vs
  57. 399 521
      src/modules/CameraAnimation/CameraAnimation.js
  58. 458 1798
      src/modules/Images360/Images360.js
  59. 207 0
      src/modules/Images360/ModelTextureMaterial.js
  60. 140 381
      src/modules/Images360/Panorama.js
  61. 44 85
      src/modules/Images360/tile/PanoRenderer.js
  62. 4 4
      src/modules/Images360/tile/QualityManager.js
  63. 127 135
      src/modules/Images360/tile/TileDownloader.js
  64. 32 64
      src/modules/Images360/tile/TilePrioritizer.js
  65. 2 3
      src/modules/Images360/tile/TileUtils.js
  66. 2 1
      src/modules/OrientedImages/OrientedImageControls.js
  67. 3 2
      src/modules/OrientedImages/OrientedImages.js
  68. 0 253
      src/modules/Particles/ParticleEditor.js
  69. 24 198
      src/modules/clipModel/Clip.js
  70. 48 259
      src/modules/datasetAlignment/Alignment.js
  71. 0 616
      src/modules/mergeModel/MergeEditor.js
  72. 0 1227
      src/modules/panoEdit/panoEditor.js
  73. 132 660
      src/modules/siteModel/BuildingBox.js
  74. 294 1001
      src/modules/siteModel/SiteModel.js
  75. 3 2
      src/navigation/DeviceOrientationControls.js
  76. 24 23
      src/navigation/EarthControls.js
  77. 109 344
      src/navigation/FirstPersonControls.js
  78. 447 846
      src/navigation/InputHandler.js
  79. 36 220
      src/navigation/OrbitControls.js
  80. 628 0
      src/navigation/PanoramaControls.js
  81. 107 0
      src/navigation/Reticule.js
  82. 74 229
      src/modules/route/RouteGuider.js
  83. 5 4
      src/navigation/VRControls.js
  84. 0 141
      src/objects/InfiniteGridHelper.js
  85. 0 350
      src/objects/Magnifier.js
  86. 0 271
      src/objects/Reticule.js
  87. 0 161
      src/objects/Tag.js
  88. 0 475
      src/objects/fireParticle/explode/ExplodeParticle.js
  89. 0 57
      src/objects/fireParticle/explode/Particle.js
  90. 0 18
      src/objects/fireParticle/explode/Util.js
  91. 0 4
      src/objects/fireParticle/explode/const.js
  92. 0 40
      src/objects/fireParticle/explode/shader.js
  93. 0 274
      src/objects/fireParticle/fire/FireParticle.js
  94. 0 63
      src/objects/fireParticle/fire/shader.js
  95. 0 57
      src/objects/fireParticle/smoke/Particle.js
  96. 0 594
      src/objects/fireParticle/smoke/SmokeParticle.js
  97. 0 44
      src/objects/fireParticle/smoke/shader.js
  98. 0 291
      src/objects/tool/Compass.js
  99. 0 229
      src/objects/tool/CurveCtrl.js
  100. 0 0
      src/objects/tool/HandleSprite.js

+ 0 - 79
examples/pano.html

@@ -1,79 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-<head>
-	<meta charset="utf-8">
-	<meta name="description" content="">
-	<meta name="author" content="">
-	<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
-	<title>Potree Viewer</title>
-
-	<link rel="stylesheet" type="text/css" href="../../build/potree/potree.css">
-	<link rel="stylesheet" type="text/css" href="../../libs/jquery-ui/jquery-ui.min.css">
-	<link rel="stylesheet" type="text/css" href="../../libs/openlayers3/ol.css">
-	<link rel="stylesheet" type="text/css" href="../../libs/spectrum/spectrum.css">
-	<link rel="stylesheet" type="text/css" href="../../libs/jstree/themes/mixed/style.css">
-</head>
-
-<body>
-	<script src="../../libs/jquery/jquery-3.1.1.min.js"></script>
-	<script src="../../libs/spectrum/spectrum.js"></script>
-	<script src="../../libs/jquery-ui/jquery-ui.min.js"></script>
-	<script src="../../libs/other/BinaryHeap.js"></script>
-	<script src="../../libs/tween/tween.min.js"></script>
-	<script src="../../libs/d3/d3.js"></script>
-	<script src="../../libs/proj4/proj4.js"></script> 
-	
-    
-	<script src="../../libs/openlayers3/ol.js"></script>
-	<script src="../../libs/i18next/i18next.js"></script>
-	<script src="../../libs/jstree/jstree.js"></script>
-	<script src="../../build/potree/potree.js"></script>
-	<script src="../../libs/plasio/js/laslaz.js"></script>
-	
-	
-	<div class="potree_container" style="position: absolute; width: 100%; height: 100%; left: 0px; top: 0px; ">
-		<div id="potree_render_area" style="background-image: url('../../build/potree/resources/images/background.jpg');">
-            
-		</div>
-		<div id="potree_sidebar_container"> </div>
-	</div>
-	
-	<script type="module">
-
-	import * as THREE from "../libs/three.js/build/three.module.js";
-    import browser from '../src/utils/browser.js' //这里必须加.js
-     
-        /*var number = window.location.href.substring(window.location.href.indexOf("=") + 1);
-        if (number.indexOf("&") != -1) {
-            number = number.substring(0, number.indexOf("&"));
-        }
-        if (number.indexOf("#") != -1) {
-            number = number.substring(0, number.indexOf("#"));
-        }*/
-        
-        var number = browser.urlHasValue('m',true);
-        console.log(number)
-        Potree.panoEditStart(document.getElementById("potree_render_area"),null, number);
-        
-          
-		/*
-        数据集校准 平移后
-        单个数据集:
-        
-        点云的本地位置是一样的 。说明:单个数据集时点云最终平移量为0,同理漫游点也是 
-        多个数据集时,参照为第一个dataset,见GeoTransformationService.setOffsetFromGlobal。所以第一个数据集的位置为000,其他的不是。因此本地坐标是不固定的,只有指定了参考数据集才能确定,如果去掉第一个数据集下一次显示的坐标就不同了,但是不影响相对位置所以看起来一样。
-        (注意:navvis平移后要刷新location才生效。)
-        
-        
-        var view = window.IV.getMainView() 
-        view.ImageService.images.forEach(e=>console.log(e.id + ": "+e.location.toArray()))
-        
-        
-        images360.panos.forEach(e=>console.log(e.id + ": "+e.position.toArray()))
-        */        
-		
-	</script>
-	
-	
-  </body>
-</html>

+ 0 - 2
gulpfile.js

@@ -22,7 +22,6 @@ let paths = {
 	html: [
 		"src/viewer/potree.css",
 		"src/viewer/sidebar.html",
-        "src/viewer/sidebar2.html",
 		"src/viewer/profile.html"
 	],
 	resources: [
@@ -90,7 +89,6 @@ let shaders = [
 gulp.task('webserver', gulp.series(async function() {
 	server = connect.server({
 		port: 1234,
-        host:'192.168.0.113',
 		https: false,
 	});
 }));

+ 82 - 105
libs/three.js/build/three.module.js

@@ -208,7 +208,7 @@ function EventDispatcher() {}
 
 Object.assign( EventDispatcher.prototype, {
 
-	addEventListener: function ( type, listener, importance=0 ) {//add importance
+	addEventListener: function ( type, listener ) {
 
 		if ( this._listeners === undefined ) this._listeners = {};
 
@@ -220,10 +220,10 @@ Object.assign( EventDispatcher.prototype, {
 
 		}
 
-		if ( !listeners[ type ].some(e=>e.listener == listener )  ) { 
-			//listeners[ type ].push( listener );
-            listeners[type].push({ listener,  importance});
-            listeners[type] = listeners[type].sort((e,a)=> a.importance - e.importance)//add
+		if ( listeners[ type ].indexOf( listener ) === - 1 ) {
+
+			listeners[ type ].push( listener );
+
 		}
 
 	},
@@ -234,7 +234,7 @@ Object.assign( EventDispatcher.prototype, {
 
 		const listeners = this._listeners;
 
-		return listeners[ type ] !== undefined &&  listeners[ type ].some(e=>e.listener == listener )    
+		return listeners[ type ] !== undefined && listeners[ type ].indexOf( listener ) !== - 1;
 
 	},
 
@@ -247,36 +247,20 @@ Object.assign( EventDispatcher.prototype, {
 
 		if ( listenerArray !== undefined ) {
 
-			/* const index = listenerArray.indexOf( listener );
+			const index = listenerArray.indexOf( listener );
 
 			if ( index !== - 1 ) {
 
 				listenerArray.splice( index, 1 );
 
-			} */
-
-            let item = listenerArray.find(e=>e.listener == listener)
-            item && listenerArray.splice(listenerArray.indexOf(item), 1);
+			}
 
 		}
 
 	},
-    removeEventListeners(type){//add
-		if(this._listeners && this._listeners[type] !== undefined){
-			delete this._listeners[type];
-		}
-	} ,
-    removeAllListeners(){ //add
-        this._listeners = {};
-        
-    },
-    
-    
-    
-	dispatchEvent: function ( event ) { 
-        if(typeof event == 'string'){//add
-            event = {type:event}
-        }
+
+	dispatchEvent: function ( event ) {
+
 		if ( this._listeners === undefined ) return;
 
 		const listeners = this._listeners;
@@ -287,18 +271,18 @@ Object.assign( EventDispatcher.prototype, {
 			event.target = this;
 
 			// Make a copy, in case listeners are removed while iterating.
-			 
-            for(let {listener} of listenerArray.slice(0)){
-				let result = listener.call(this, event);   //add stopContinue
-                if(result && result.stopContinue){
-                    break
-                }
+			const array = listenerArray.slice( 0 );
+
+			for ( let i = 0, l = array.length; i < l; i ++ ) {
+
+				array[ i ].call( this, event );
+
 			}
 
 		}
 
 	}
-    
+
 } );
 
 const _lut = [];
@@ -6845,11 +6829,8 @@ Object3D.prototype = Object.assign( Object.create( EventDispatcher.prototype ),
 
 	traverse: function ( callback ) {
 
-		let result = callback( this );
-        if(result && result.stopContinue){//xzw add
-            return 
-        }
-             
+		callback( this );
+
 		const children = this.children;
 
 		for ( let i = 0, l = children.length; i < l; i ++ ) {
@@ -8543,7 +8524,7 @@ Material.prototype = Object.assign( Object.create( EventDispatcher.prototype ),
 
 			if ( currentValue === undefined ) {
 
-				//console.warn( 'THREE.' + this.type + ': \'' + key + '\' is not a property of this material.' );
+				console.warn( 'THREE.' + this.type + ': \'' + key + '\' is not a property of this material.' );
 				continue;
 
 			}
@@ -8715,7 +8696,7 @@ Material.prototype = Object.assign( Object.create( EventDispatcher.prototype ),
 		if ( this.polygonOffsetFactor !== 0 ) data.polygonOffsetFactor = this.polygonOffsetFactor;
 		if ( this.polygonOffsetUnits !== 0 ) data.polygonOffsetUnits = this.polygonOffsetUnits;
 
-		if ( this.lineWidth && this.lineWidth !== 1 ) data.lineWidth = this.lineWidth;
+		if ( this.linewidth && this.linewidth !== 1 ) data.linewidth = this.linewidth;
 		if ( this.dashSize !== undefined ) data.dashSize = this.dashSize;
 		if ( this.gapSize !== undefined ) data.gapSize = this.gapSize;
 		if ( this.scale !== undefined ) data.scale = this.scale;
@@ -8726,7 +8707,7 @@ Material.prototype = Object.assign( Object.create( EventDispatcher.prototype ),
 		if ( this.premultipliedAlpha === true ) data.premultipliedAlpha = this.premultipliedAlpha;
 
 		if ( this.wireframe === true ) data.wireframe = this.wireframe;
-		if ( this.wireframelineWidth > 1 ) data.wireframelineWidth = this.wireframelineWidth;
+		if ( this.wireframeLinewidth > 1 ) data.wireframeLinewidth = this.wireframeLinewidth;
 		if ( this.wireframeLinecap !== 'round' ) data.wireframeLinecap = this.wireframeLinecap;
 		if ( this.wireframeLinejoin !== 'round' ) data.wireframeLinejoin = this.wireframeLinejoin;
 
@@ -8900,7 +8881,7 @@ Object.defineProperty( Material.prototype, 'needsUpdate', {
  *  depthWrite: <bool>,
  *
  *  wireframe: <boolean>,
- *  wireframelineWidth: <float>,
+ *  wireframeLinewidth: <float>,
  *
  *  skinning: <bool>,
  *  morphTargets: <bool>
@@ -8933,7 +8914,7 @@ function MeshBasicMaterial( parameters ) {
 	this.refractionRatio = 0.98;
 
 	this.wireframe = false;
-	this.wireframelineWidth = 1;
+	this.wireframeLinewidth = 1;
 	this.wireframeLinecap = 'round';
 	this.wireframeLinejoin = 'round';
 
@@ -8973,7 +8954,7 @@ MeshBasicMaterial.prototype.copy = function ( source ) {
 	this.refractionRatio = source.refractionRatio;
 
 	this.wireframe = source.wireframe;
-	this.wireframelineWidth = source.wireframelineWidth;
+	this.wireframeLinewidth = source.wireframeLinewidth;
 	this.wireframeLinecap = source.wireframeLinecap;
 	this.wireframeLinejoin = source.wireframeLinejoin;
 
@@ -11719,7 +11700,7 @@ var default_fragment = "void main() {\n\tgl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0
  *  vertexShader: <string>,
  *
  *  wireframe: <boolean>,
- *  wireframelineWidth: <float>,
+ *  wireframeLinewidth: <float>,
  *
  *  lights: <bool>,
  *
@@ -11741,10 +11722,10 @@ function ShaderMaterial( parameters ) {
 	this.vertexShader = default_vertex;
 	this.fragmentShader = default_fragment;
 
-	this.lineWidth = 1;
+	this.linewidth = 1;
 
 	this.wireframe = false;
-	this.wireframelineWidth = 1;
+	this.wireframeLinewidth = 1;
 
 	this.fog = false; // set to use scene fog
 	this.lights = false; // set to use scene lights
@@ -11805,7 +11786,7 @@ ShaderMaterial.prototype.copy = function ( source ) {
 	this.defines = Object.assign( {}, source.defines );
 
 	this.wireframe = source.wireframe;
-	this.wireframelineWidth = source.wireframelineWidth;
+	this.wireframeLinewidth = source.wireframeLinewidth;
 
 	this.lights = source.lights;
 	this.clipping = source.clipping;
@@ -18896,7 +18877,7 @@ function WebGLRenderStates( extensions, capabilities ) {
  *  displacementBias: <float>,
  *
  *  wireframe: <boolean>,
- *  wireframelineWidth: <float>
+ *  wireframeLinewidth: <float>
  * }
  */
 
@@ -18920,7 +18901,7 @@ function MeshDepthMaterial( parameters ) {
 	this.displacementBias = 0;
 
 	this.wireframe = false;
-	this.wireframelineWidth = 1;
+	this.wireframeLinewidth = 1;
 
 	this.fog = false;
 
@@ -18951,7 +18932,7 @@ MeshDepthMaterial.prototype.copy = function ( source ) {
 	this.displacementBias = source.displacementBias;
 
 	this.wireframe = source.wireframe;
-	this.wireframelineWidth = source.wireframelineWidth;
+	this.wireframeLinewidth = source.wireframeLinewidth;
 
 	return this;
 
@@ -19396,8 +19377,8 @@ function WebGLShadowMap( _renderer, _objects, maxTextureSize ) {
 		result.clippingPlanes = material.clippingPlanes;
 		result.clipIntersection = material.clipIntersection;
 
-		result.wireframelineWidth = material.wireframelineWidth;
-		result.lineWidth = material.lineWidth;
+		result.wireframeLinewidth = material.wireframeLinewidth;
+		result.linewidth = material.linewidth;
 
 		if ( light.isPointLight === true && result.isMeshDistanceMaterial === true ) {
 
@@ -19799,7 +19780,7 @@ function WebGLState( gl, extensions, capabilities ) {
 	let currentFlipSided = null;
 	let currentCullFace = null;
 
-	let currentlineWidth = null;
+	let currentLineWidth = null;
 
 	let currentPolygonOffsetFactor = null;
 	let currentPolygonOffsetUnits = null;
@@ -20168,13 +20149,13 @@ function WebGLState( gl, extensions, capabilities ) {
 
 	}
 
-	function setlineWidth( width ) {
+	function setLineWidth( width ) {
 
-		if ( width !== currentlineWidth ) {
+		if ( width !== currentLineWidth ) {
 
 			if ( lineWidthAvailable ) gl.lineWidth( width );
 
-			currentlineWidth = width;
+			currentLineWidth = width;
 
 		}
 
@@ -20365,7 +20346,7 @@ function WebGLState( gl, extensions, capabilities ) {
 		currentFlipSided = null;
 		currentCullFace = null;
 
-		currentlineWidth = null;
+		currentLineWidth = null;
 
 		currentPolygonOffsetFactor = null;
 		currentPolygonOffsetUnits = null;
@@ -20395,7 +20376,7 @@ function WebGLState( gl, extensions, capabilities ) {
 		setFlipSided: setFlipSided,
 		setCullFace: setCullFace,
 
-		setlineWidth: setlineWidth,
+		setLineWidth: setLineWidth,
 		setPolygonOffset: setPolygonOffset,
 
 		setScissorTest: setScissorTest,
@@ -23703,23 +23684,19 @@ function WebGLRenderer( parameters ) {
 
 		_width = width;
 		_height = height;
-        
-        //if(!window.unableSetSize){ 
-            _canvas.width = Math.floor( width * _pixelRatio );
-            _canvas.height = Math.floor( height * _pixelRatio );
-        
-        
-        
-            if ( updateStyle !== false ) {
 
-                _canvas.style.width = width + 'px';
-                _canvas.style.height = height + 'px';
+		_canvas.width = Math.floor( width * _pixelRatio );
+		_canvas.height = Math.floor( height * _pixelRatio );
+
+		if ( updateStyle !== false ) {
+
+			_canvas.style.width = width + 'px';
+			_canvas.style.height = height + 'px';
+
+		}
+
+		this.setViewport( 0, 0, width, height );
 
-            }
-            
-            
-            this.setViewport( 0, 0, width, height );
-        //}
 	};
 
 	this.getDrawingBufferSize = function ( target ) {
@@ -24125,7 +24102,7 @@ function WebGLRenderer( parameters ) {
 
 			if ( material.wireframe === true ) {
 
-				state.setlineWidth( material.wireframelineWidth * getTargetPixelRatio() );
+				state.setLineWidth( material.wireframeLinewidth * getTargetPixelRatio() );
 				renderer.setMode( 1 );
 
 			} else {
@@ -24136,11 +24113,11 @@ function WebGLRenderer( parameters ) {
 
 		} else if ( object.isLine ) {
 
-			let lineWidth = material.lineWidth;
+			let lineWidth = material.linewidth;
 
 			if ( lineWidth === undefined ) lineWidth = 1; // Not using Line*Material
 
-			state.setlineWidth( lineWidth * getTargetPixelRatio() );
+			state.setLineWidth( lineWidth * getTargetPixelRatio() );
 
 			if ( object.isLineSegments ) {
 
@@ -26807,7 +26784,7 @@ InstancedMesh.prototype = Object.assign( Object.create( Mesh.prototype ), {
  *  color: <hex>,
  *  opacity: <float>,
  *
- *  lineWidth: <float>,
+ *  linewidth: <float>,
  *  linecap: "round",
  *  linejoin: "round"
  * }
@@ -26821,7 +26798,7 @@ function LineBasicMaterial( parameters ) {
 
 	this.color = new Color( 0xffffff );
 
-	this.lineWidth = 1;
+	this.linewidth = 1;
 	this.linecap = 'round';
 	this.linejoin = 'round';
 
@@ -26842,7 +26819,7 @@ LineBasicMaterial.prototype.copy = function ( source ) {
 
 	this.color.copy( source.color );
 
-	this.lineWidth = source.lineWidth;
+	this.linewidth = source.linewidth;
 	this.linecap = source.linecap;
 	this.linejoin = source.linejoin;
 
@@ -33508,7 +33485,7 @@ RawShaderMaterial.prototype.isRawShaderMaterial = true;
  *  refractionRatio: <float>,
  *
  *  wireframe: <boolean>,
- *  wireframelineWidth: <float>,
+ *  wireframeLinewidth: <float>,
  *
  *  skinning: <bool>,
  *  morphTargets: <bool>,
@@ -33563,7 +33540,7 @@ function MeshStandardMaterial( parameters ) {
 	this.refractionRatio = 0.98;
 
 	this.wireframe = false;
-	this.wireframelineWidth = 1;
+	this.wireframeLinewidth = 1;
 	this.wireframeLinecap = 'round';
 	this.wireframeLinejoin = 'round';
 
@@ -33627,7 +33604,7 @@ MeshStandardMaterial.prototype.copy = function ( source ) {
 	this.refractionRatio = source.refractionRatio;
 
 	this.wireframe = source.wireframe;
-	this.wireframelineWidth = source.wireframelineWidth;
+	this.wireframeLinewidth = source.wireframeLinewidth;
 	this.wireframeLinecap = source.wireframeLinecap;
 	this.wireframeLinejoin = source.wireframeLinejoin;
 
@@ -33786,7 +33763,7 @@ MeshPhysicalMaterial.prototype.copy = function ( source ) {
  *  refractionRatio: <float>,
  *
  *  wireframe: <boolean>,
- *  wireframelineWidth: <float>,
+ *  wireframeLinewidth: <float>,
  *
  *  skinning: <bool>,
  *  morphTargets: <bool>,
@@ -33837,7 +33814,7 @@ function MeshPhongMaterial( parameters ) {
 	this.refractionRatio = 0.98;
 
 	this.wireframe = false;
-	this.wireframelineWidth = 1;
+	this.wireframeLinewidth = 1;
 	this.wireframeLinecap = 'round';
 	this.wireframeLinejoin = 'round';
 
@@ -33895,7 +33872,7 @@ MeshPhongMaterial.prototype.copy = function ( source ) {
 	this.refractionRatio = source.refractionRatio;
 
 	this.wireframe = source.wireframe;
-	this.wireframelineWidth = source.wireframelineWidth;
+	this.wireframeLinewidth = source.wireframeLinewidth;
 	this.wireframeLinecap = source.wireframeLinecap;
 	this.wireframeLinejoin = source.wireframeLinejoin;
 
@@ -33938,7 +33915,7 @@ MeshPhongMaterial.prototype.copy = function ( source ) {
  *  alphaMap: new THREE.Texture( <Image> ),
  *
  *  wireframe: <boolean>,
- *  wireframelineWidth: <float>,
+ *  wireframeLinewidth: <float>,
  *
  *  skinning: <bool>,
  *  morphTargets: <bool>,
@@ -33983,7 +33960,7 @@ function MeshToonMaterial( parameters ) {
 	this.alphaMap = null;
 
 	this.wireframe = false;
-	this.wireframelineWidth = 1;
+	this.wireframeLinewidth = 1;
 	this.wireframeLinecap = 'round';
 	this.wireframeLinejoin = 'round';
 
@@ -34033,7 +34010,7 @@ MeshToonMaterial.prototype.copy = function ( source ) {
 	this.alphaMap = source.alphaMap;
 
 	this.wireframe = source.wireframe;
-	this.wireframelineWidth = source.wireframelineWidth;
+	this.wireframeLinewidth = source.wireframeLinewidth;
 	this.wireframeLinecap = source.wireframeLinecap;
 	this.wireframeLinejoin = source.wireframeLinejoin;
 
@@ -34061,7 +34038,7 @@ MeshToonMaterial.prototype.copy = function ( source ) {
  *  displacementBias: <float>,
  *
  *  wireframe: <boolean>,
- *  wireframelineWidth: <float>
+ *  wireframeLinewidth: <float>
  *
  *  skinning: <bool>,
  *  morphTargets: <bool>,
@@ -34087,7 +34064,7 @@ function MeshNormalMaterial( parameters ) {
 	this.displacementBias = 0;
 
 	this.wireframe = false;
-	this.wireframelineWidth = 1;
+	this.wireframeLinewidth = 1;
 
 	this.fog = false;
 
@@ -34120,7 +34097,7 @@ MeshNormalMaterial.prototype.copy = function ( source ) {
 	this.displacementBias = source.displacementBias;
 
 	this.wireframe = source.wireframe;
-	this.wireframelineWidth = source.wireframelineWidth;
+	this.wireframeLinewidth = source.wireframeLinewidth;
 
 	this.skinning = source.skinning;
 	this.morphTargets = source.morphTargets;
@@ -34157,7 +34134,7 @@ MeshNormalMaterial.prototype.copy = function ( source ) {
  *  refractionRatio: <float>,
  *
  *  wireframe: <boolean>,
- *  wireframelineWidth: <float>,
+ *  wireframeLinewidth: <float>,
  *
  *  skinning: <bool>,
  *  morphTargets: <bool>,
@@ -34195,7 +34172,7 @@ function MeshLambertMaterial( parameters ) {
 	this.refractionRatio = 0.98;
 
 	this.wireframe = false;
-	this.wireframelineWidth = 1;
+	this.wireframeLinewidth = 1;
 	this.wireframeLinecap = 'round';
 	this.wireframeLinejoin = 'round';
 
@@ -34240,7 +34217,7 @@ MeshLambertMaterial.prototype.copy = function ( source ) {
 	this.refractionRatio = source.refractionRatio;
 
 	this.wireframe = source.wireframe;
-	this.wireframelineWidth = source.wireframelineWidth;
+	this.wireframeLinewidth = source.wireframeLinewidth;
 	this.wireframeLinecap = source.wireframeLinecap;
 	this.wireframeLinejoin = source.wireframeLinejoin;
 
@@ -34358,7 +34335,7 @@ MeshMatcapMaterial.prototype.copy = function ( source ) {
  *  color: <hex>,
  *  opacity: <float>,
  *
- *  lineWidth: <float>,
+ *  linewidth: <float>,
  *
  *  scale: <float>,
  *  dashSize: <float>,
@@ -36777,8 +36754,8 @@ FileLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
 					for ( let i = 0, il = callbacks.length; i < il; i ++ ) {
 
 						const callback = callbacks[ i ];
-						if ( callback.onLoad ) callback.onLoad( response, event.total); //xzw add event.total
-  
+						if ( callback.onLoad ) callback.onLoad( response );
+
 					}
 
 					scope.manager.itemEnd( url );
@@ -40402,13 +40379,13 @@ MaterialLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
 		if ( json.stencilZPass !== undefined ) material.stencilZPass = json.stencilZPass;
 
 		if ( json.wireframe !== undefined ) material.wireframe = json.wireframe;
-		if ( json.wireframelineWidth !== undefined ) material.wireframelineWidth = json.wireframelineWidth;
+		if ( json.wireframeLinewidth !== undefined ) material.wireframeLinewidth = json.wireframeLinewidth;
 		if ( json.wireframeLinecap !== undefined ) material.wireframeLinecap = json.wireframeLinecap;
 		if ( json.wireframeLinejoin !== undefined ) material.wireframeLinejoin = json.wireframeLinejoin;
 
 		if ( json.rotation !== undefined ) material.rotation = json.rotation;
 
-		if ( json.lineWidth !== 1 ) material.lineWidth = json.lineWidth;
+		if ( json.linewidth !== 1 ) material.linewidth = json.linewidth;
 		if ( json.dashSize !== undefined ) material.dashSize = json.dashSize;
 		if ( json.gapSize !== undefined ) material.gapSize = json.gapSize;
 		if ( json.scale !== undefined ) material.scale = json.scale;
@@ -42120,7 +42097,7 @@ ImageBitmapLoader.prototype = Object.assign( Object.create( Loader.prototype ),
 			return res.blob();
 
 		} ).then( function ( blob ) {
-            //console.log('getBlob', url   )
+
 			return createImageBitmap( blob, scope.options );
 
 		} ).then( function ( imageBitmap ) {
@@ -42131,9 +42108,9 @@ ImageBitmapLoader.prototype = Object.assign( Object.create( Loader.prototype ),
 
 			scope.manager.itemEnd( url );
 
-		} ).catch( function ( e ) { 
-            //console.log('error', url, e)
-			if ( onError ) onError( e, url );
+		} ).catch( function ( e ) {
+
+			if ( onError ) onError( e );
 
 			scope.manager.itemError( url );
 			scope.manager.itemEnd( url );

+ 12 - 7
libs/three.js/lines/Line2.js

@@ -2,18 +2,23 @@ import { LineSegments2 } from '../lines/LineSegments2.js';
 import { LineGeometry } from '../lines/LineGeometry.js';
 import { LineMaterial } from '../lines/LineMaterial.js';
 
-class Line2 extends LineSegments2 {
+var Line2 = function ( geometry, material ) {
 
-	constructor( geometry = new LineGeometry(), material = new LineMaterial( { color: Math.random() * 0xffffff } ) ) {
+	if ( geometry === undefined ) geometry = new LineGeometry();
+	if ( material === undefined ) material = new LineMaterial( { color: Math.random() * 0xffffff } );
 
-		super( geometry, material );
+	LineSegments2.call( this, geometry, material );
 
-		this.isLine2 = true;
+	this.type = 'Line2';
 
-		this.type = 'Line2';
+};
 
-	}
+Line2.prototype = Object.assign( Object.create( LineSegments2.prototype ), {
 
-}
+	constructor: Line2,
+
+	isLine2: true
+
+} );
 
 export { Line2 };

+ 40 - 22
libs/three.js/lines/LineGeometry.js

@@ -1,25 +1,27 @@
 import { LineSegmentsGeometry } from '../lines/LineSegmentsGeometry.js';
 
-class LineGeometry extends LineSegmentsGeometry {
+var LineGeometry = function () {
 
-	constructor() {
+	LineSegmentsGeometry.call( this );
 
-		super();
+	this.type = 'LineGeometry';
 
-		this.isLineGeometry = true;
+};
 
-		this.type = 'LineGeometry';
+LineGeometry.prototype = Object.assign( Object.create( LineSegmentsGeometry.prototype ), {
 
-	}
+	constructor: LineGeometry,
+
+	isLineGeometry: true,
 
-	setPositions( array ) {
+	setPositions: function ( array ) {
 
 		// converts [ x1, y1, z1,  x2, y2, z2, ... ] to pairs format
 
-		const length = array.length - 3;
-		const points = new Float32Array( 2 * length );
+		var length = array.length - 3;
+		var points = new Float32Array( 2 * length );
 
-		for ( let i = 0; i < length; i += 3 ) {
+		for ( var i = 0; i < length; i += 3 ) {
 
 			points[ 2 * i ] = array[ i ];
 			points[ 2 * i + 1 ] = array[ i + 1 ];
@@ -31,20 +33,20 @@ class LineGeometry extends LineSegmentsGeometry {
 
 		}
 
-		super.setPositions( points );
+		LineSegmentsGeometry.prototype.setPositions.call( this, points );
 
 		return this;
 
-	}
+	},
 
-	setColors( array ) {
+	setColors: function ( array ) {
 
 		// converts [ r1, g1, b1,  r2, g2, b2, ... ] to pairs format
 
-		const length = array.length - 3;
-		const colors = new Float32Array( 2 * length );
+		var length = array.length - 3;
+		var colors = new Float32Array( 2 * length );
 
-		for ( let i = 0; i < length; i += 3 ) {
+		for ( var i = 0; i < length; i += 3 ) {
 
 			colors[ 2 * i ] = array[ i ];
 			colors[ 2 * i + 1 ] = array[ i + 1 ];
@@ -56,24 +58,40 @@ class LineGeometry extends LineSegmentsGeometry {
 
 		}
 
-		super.setColors( colors );
+		LineSegmentsGeometry.prototype.setColors.call( this, colors );
 
 		return this;
 
-	}
+	},
+
+	fromLine: function ( line ) {
+
+		var geometry = line.geometry;
+
+		if ( geometry.isGeometry ) {
 
-	fromLine( line ) {
+			this.setPositions( geometry.vertices );
 
-		const geometry = line.geometry;
+		} else if ( geometry.isBufferGeometry ) {
 
-		this.setPositions( geometry.attributes.position.array ); // assumes non-indexed
+			this.setPositions( geometry.attributes.position.array ); // assumes non-indexed
+
+		}
 
 		// set colors, maybe
 
 		return this;
 
+	},
+
+	copy: function ( /* source */ ) {
+
+		// todo
+
+		return this;
+
 	}
 
-}
+} );
 
 export { LineGeometry };

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 241 - 560
libs/three.js/lines/LineMaterial.js


+ 128 - 274
libs/three.js/lines/LineSegments2.js

@@ -1,355 +1,209 @@
 import {
-	Box3,
 	InstancedInterleavedBuffer,
 	InterleavedBufferAttribute,
 	Line3,
 	MathUtils,
 	Matrix4,
 	Mesh,
-	Sphere,
 	Vector3,
 	Vector4
-} from '../build/three.module.js'; 
+} from '../build/three.module.js';
 import { LineSegmentsGeometry } from '../lines/LineSegmentsGeometry.js';
 import { LineMaterial } from '../lines/LineMaterial.js';
 
-const _start = new Vector3();
-const _end = new Vector3();
+var LineSegments2 = function ( geometry, material ) {
 
-const _start4 = new Vector4();
-const _end4 = new Vector4();
+	if ( geometry === undefined ) geometry = new LineSegmentsGeometry();
+	if ( material === undefined ) material = new LineMaterial( { color: Math.random() * 0xffffff } );
 
-const _ssOrigin = new Vector4();
-const _ssOrigin3 = new Vector3();
-const _mvMatrix = new Matrix4();
-const _line = new Line3();
-const _closestPoint = new Vector3();
+	Mesh.call( this, geometry, material );
 
-const _box = new Box3();
-const _sphere = new Sphere();
-const _clipToWorldVector = new Vector4();
+	this.type = 'LineSegments2';
 
-let _ray, _instanceStart, _instanceEnd, _lineWidth;
+};
 
-// Returns the margin required to expand by in world space given the distance from the camera,
-// line width, resolution, and camera projection
-function getWorldSpaceHalfWidth( camera, distance, resolution ) {
+LineSegments2.prototype = Object.assign( Object.create( Mesh.prototype ), {
 
-	// transform into clip space, adjust the x and y values by the pixel width offset, then
-	// transform back into world space to get world offset. Note clip space is [-1, 1] so full
-	// width does not need to be halved.
-	_clipToWorldVector.set( 0, 0, - distance, 1.0 ).applyMatrix4( camera.projectionMatrix );
-	_clipToWorldVector.multiplyScalar( 1.0 / _clipToWorldVector.w );
-	_clipToWorldVector.x = _lineWidth / resolution.width;
-	_clipToWorldVector.y = _lineWidth / resolution.height;
-	_clipToWorldVector.applyMatrix4( camera.projectionMatrixInverse );
-	_clipToWorldVector.multiplyScalar( 1.0 / _clipToWorldVector.w );
+	constructor: LineSegments2,
 
-	return Math.abs( Math.max( _clipToWorldVector.x, _clipToWorldVector.y ) );
+	isLineSegments2: true,
 
-}
+	computeLineDistances: ( function () { // for backwards-compatability, but could be a method of LineSegmentsGeometry...
 
-function raycastWorldUnits( lineSegments, intersects ) {
+		var start = new Vector3();
+		var end = new Vector3();
 
-	for ( let i = 0, l = _instanceStart.count; i < l; i ++ ) {
+		return function computeLineDistances() {
 
-		_line.start.fromBufferAttribute( _instanceStart, i );
-		_line.end.fromBufferAttribute( _instanceEnd, i );
+			var geometry = this.geometry;
 
-		const pointOnLine = new Vector3();
-		const point = new Vector3();
+			var instanceStart = geometry.attributes.instanceStart;
+			var instanceEnd = geometry.attributes.instanceEnd;
+			var lineDistances = new Float32Array( 2 * instanceStart.data.count );
 
-		_ray.distanceSqToSegment( _line.start, _line.end, point, pointOnLine );
-		const isInside = point.distanceTo( pointOnLine ) < _lineWidth * 0.5;
+			for ( var i = 0, j = 0, l = instanceStart.data.count; i < l; i ++, j += 2 ) {
 
-		if ( isInside ) {
+				start.fromBufferAttribute( instanceStart, i );
+				end.fromBufferAttribute( instanceEnd, i );
 
-			intersects.push( {
-				point,
-				pointOnLine,
-				distance: _ray.origin.distanceTo( point ),
-				object: lineSegments,
-				face: null,
-				faceIndex: i,
-				uv: null,
-				uv2: null,
-			} );
+				lineDistances[ j ] = ( j === 0 ) ? 0 : lineDistances[ j - 1 ];
+				lineDistances[ j + 1 ] = lineDistances[ j ] + start.distanceTo( end );
 
-		}
+			}
 
-	}
+			var instanceDistanceBuffer = new InstancedInterleavedBuffer( lineDistances, 2, 1 ); // d0, d1
 
-}
+			geometry.setAttribute( 'instanceDistanceStart', new InterleavedBufferAttribute( instanceDistanceBuffer, 1, 0 ) ); // d0
+			geometry.setAttribute( 'instanceDistanceEnd', new InterleavedBufferAttribute( instanceDistanceBuffer, 1, 1 ) ); // d1
 
-function raycastScreenSpace( lineSegments, camera, intersects ) {
+			return this;
 
-	const projectionMatrix = camera.projectionMatrix;
-	const material = lineSegments.material;
-	const resolution = material.resolution;
-	const matrixWorld = lineSegments.matrixWorld;
+		};
 
-	const geometry = lineSegments.geometry;
-	const instanceStart = geometry.attributes.instanceStart;
-	const instanceEnd = geometry.attributes.instanceEnd;
+	}() ),
 
-	const near = - camera.near;
+	raycast: ( function () {
 
-	//
+		var start = new Vector4();
+		var end = new Vector4();
 
-	// pick a point 1 unit out along the ray to avoid the ray origin
-	// sitting at the camera origin which will cause "w" to be 0 when
-	// applying the projection matrix.
-	_ray.at( 1, _ssOrigin );
+		var ssOrigin = new Vector4();
+		var ssOrigin3 = new Vector3();
+		var mvMatrix = new Matrix4();
+		var line = new Line3();
+		var closestPoint = new Vector3();
 
-	// ndc space [ - 1.0, 1.0 ]
-	_ssOrigin.w = 1;
-	_ssOrigin.applyMatrix4( camera.matrixWorldInverse );
-	_ssOrigin.applyMatrix4( projectionMatrix );
-	_ssOrigin.multiplyScalar( 1 / _ssOrigin.w );
+		return function raycast( raycaster, intersects ) {
 
-	// screen space
-	_ssOrigin.x *= resolution.x / 2;
-	_ssOrigin.y *= resolution.y / 2;
-	_ssOrigin.z = 0;
+			if ( raycaster.camera === null ) {
 
-	_ssOrigin3.copy( _ssOrigin );
+				console.error( 'LineSegments2: "Raycaster.camera" needs to be set in order to raycast against LineSegments2.' );
 
-	_mvMatrix.multiplyMatrices( camera.matrixWorldInverse, matrixWorld );
+			}
 
-	for ( let i = 0, l = instanceStart.count; i < l; i ++ ) {
+			var threshold = ( raycaster.params.Line2 !== undefined ) ? raycaster.params.Line2.threshold || 0 : 0;
 
-		_start4.fromBufferAttribute( instanceStart, i );
-		_end4.fromBufferAttribute( instanceEnd, i );
+			var ray = raycaster.ray;
+			var camera = raycaster.camera;
+			var projectionMatrix = camera.projectionMatrix;
 
-		_start4.w = 1;
-		_end4.w = 1;
+			var geometry = this.geometry;
+			var material = this.material;
+			var resolution = material.resolution;
+			var lineWidth = material.linewidth + threshold;
 
-		// camera space
-		_start4.applyMatrix4( _mvMatrix );
-		_end4.applyMatrix4( _mvMatrix );
+			var instanceStart = geometry.attributes.instanceStart;
+			var instanceEnd = geometry.attributes.instanceEnd;
 
-		// skip the segment if it's entirely behind the camera
-		const isBehindCameraNear = _start4.z > near && _end4.z > near;
-		if ( isBehindCameraNear ) {
+			// pick a point 1 unit out along the ray to avoid the ray origin
+			// sitting at the camera origin which will cause "w" to be 0 when
+			// applying the projection matrix.
+			ray.at( 1, ssOrigin );
 
-			continue;
+			// ndc space [ - 1.0, 1.0 ]
+			ssOrigin.w = 1;
+			ssOrigin.applyMatrix4( camera.matrixWorldInverse );
+			ssOrigin.applyMatrix4( projectionMatrix );
+			ssOrigin.multiplyScalar( 1 / ssOrigin.w );
 
-		}
+			// screen space
+			ssOrigin.x *= resolution.x / 2;
+			ssOrigin.y *= resolution.y / 2;
+			ssOrigin.z = 0;
 
-		// trim the segment if it extends behind camera near
-		if ( _start4.z > near ) {
+			ssOrigin3.copy( ssOrigin );
 
-			const deltaDist = _start4.z - _end4.z;
-			const t = ( _start4.z - near ) / deltaDist;
-			_start4.lerp( _end4, t );
+			var matrixWorld = this.matrixWorld;
+			mvMatrix.multiplyMatrices( camera.matrixWorldInverse, matrixWorld );
 
-		} else if ( _end4.z > near ) {
+			for ( var i = 0, l = instanceStart.count; i < l; i ++ ) {
 
-			const deltaDist = _end4.z - _start4.z;
-			const t = ( _end4.z - near ) / deltaDist;
-			_end4.lerp( _start4, t );
+				start.fromBufferAttribute( instanceStart, i );
+				end.fromBufferAttribute( instanceEnd, i );
 
-		}
+				start.w = 1;
+				end.w = 1;
 
-		// clip space
-		_start4.applyMatrix4( projectionMatrix );
-		_end4.applyMatrix4( projectionMatrix );
+				// camera space
+				start.applyMatrix4( mvMatrix );
+				end.applyMatrix4( mvMatrix );
 
-		// ndc space [ - 1.0, 1.0 ]
-		_start4.multiplyScalar( 1 / _start4.w );
-		_end4.multiplyScalar( 1 / _end4.w );
+				// clip space
+				start.applyMatrix4( projectionMatrix );
+				end.applyMatrix4( projectionMatrix );
 
-		// screen space
-		_start4.x *= resolution.x / 2;
-		_start4.y *= resolution.y / 2;
+				// ndc space [ - 1.0, 1.0 ]
+				start.multiplyScalar( 1 / start.w );
+				end.multiplyScalar( 1 / end.w );
 
-		_end4.x *= resolution.x / 2;
-		_end4.y *= resolution.y / 2;
+				// skip the segment if it's outside the camera near and far planes
+				var isBehindCameraNear = start.z < - 1 && end.z < - 1;
+				var isPastCameraFar = start.z > 1 && end.z > 1;
+				if ( isBehindCameraNear || isPastCameraFar ) {
 
-		// create 2d segment
-		_line.start.copy( _start4 );
-		_line.start.z = 0;
+					continue;
 
-		_line.end.copy( _end4 );
-		_line.end.z = 0;
+				}
 
-		// get closest point on ray to segment
-		const param = _line.closestPointToPointParameter( _ssOrigin3, true );
-		_line.at( param, _closestPoint );
+				// screen space
+				start.x *= resolution.x / 2;
+				start.y *= resolution.y / 2;
 
-		// check if the intersection point is within clip space
-		const zPos = MathUtils.lerp( _start4.z, _end4.z, param );
-		const isInClipSpace = zPos >= - 1 && zPos <= 1;
+				end.x *= resolution.x / 2;
+				end.y *= resolution.y / 2;
 
-		const isInside = _ssOrigin3.distanceTo( _closestPoint ) < _lineWidth * 0.5;
+				// create 2d segment
+				line.start.copy( start );
+				line.start.z = 0;
 
-		if ( isInClipSpace && isInside ) {
+				line.end.copy( end );
+				line.end.z = 0;
 
-			_line.start.fromBufferAttribute( instanceStart, i );
-			_line.end.fromBufferAttribute( instanceEnd, i );
+				// get closest point on ray to segment
+				var param = line.closestPointToPointParameter( ssOrigin3, true );
+				line.at( param, closestPoint );
 
-			_line.start.applyMatrix4( matrixWorld );
-			_line.end.applyMatrix4( matrixWorld );
+				// check if the intersection point is within clip space
+				var zPos = MathUtils.lerp( start.z, end.z, param );
+				var isInClipSpace = zPos >= - 1 && zPos <= 1;
 
-			const pointOnLine = new Vector3();
-			const point = new Vector3();
+				var isInside = ssOrigin3.distanceTo( closestPoint ) < lineWidth * 0.5;
 
-			_ray.distanceSqToSegment( _line.start, _line.end, point, pointOnLine );
+				if ( isInClipSpace && isInside ) {
 
-			intersects.push( {
-				point: point,
-				pointOnLine: pointOnLine,
-				distance: _ray.origin.distanceTo( point ),
-				object: lineSegments,
-				face: null,
-				faceIndex: i,
-				uv: null,
-				uv2: null,
-			} );
+					line.start.fromBufferAttribute( instanceStart, i );
+					line.end.fromBufferAttribute( instanceEnd, i );
 
-		}
+					line.start.applyMatrix4( matrixWorld );
+					line.end.applyMatrix4( matrixWorld );
 
-	}
+					var pointOnLine = new Vector3();
+					var point = new Vector3();
 
-}
+					ray.distanceSqToSegment( line.start, line.end, point, pointOnLine );
 
-class LineSegments2 extends Mesh {
+					intersects.push( {
 
-	constructor( geometry = new LineSegmentsGeometry(), material = new LineMaterial( { color: Math.random() * 0xffffff } ) ) {
+						point: point,
+						pointOnLine: pointOnLine,
+						distance: ray.origin.distanceTo( point ),
 
-		super( geometry, material );
+						object: this,
+						face: null,
+						faceIndex: i,
+						uv: null,
+						uv2: null,
 
-		this.isLineSegments2 = true;
+					} );
 
-		this.type = 'LineSegments2';
+				}
 
-	}
+			}
 
-	// for backwards-compatibility, but could be a method of LineSegmentsGeometry...
+		};
 
-	computeLineDistances() {
+	}() )
 
-		const geometry = this.geometry;
-
-		const instanceStart = geometry.attributes.instanceStart;
-		const instanceEnd = geometry.attributes.instanceEnd;
-		const lineDistances = new Float32Array( 2 * instanceStart.count );
-
-		for ( let i = 0, j = 0, l = instanceStart.count; i < l; i ++, j += 2 ) {
-
-			_start.fromBufferAttribute( instanceStart, i );
-			_end.fromBufferAttribute( instanceEnd, i );
-
-			lineDistances[ j ] = ( j === 0 ) ? 0 : lineDistances[ j - 1 ];
-			lineDistances[ j + 1 ] = lineDistances[ j ] + _start.distanceTo( _end );
-
-		}
-
-		const instanceDistanceBuffer = new InstancedInterleavedBuffer( lineDistances, 2, 1 ); // d0, d1
-
-		geometry.setAttribute( 'instanceDistanceStart', new InterleavedBufferAttribute( instanceDistanceBuffer, 1, 0 ) ); // d0
-		geometry.setAttribute( 'instanceDistanceEnd', new InterleavedBufferAttribute( instanceDistanceBuffer, 1, 1 ) ); // d1
-
-		return this;
-
-	}
-
-	raycast( raycaster, intersects ) {
-
-		const worldUnits = this.material.worldUnits;
-		const camera = raycaster.camera;
-
-		if ( camera === null && ! worldUnits ) {
-
-			console.error( 'LineSegments2: "Raycaster.camera" needs to be set in order to raycast against LineSegments2 while worldUnits is set to false.' );
-
-		}
-
-		const threshold = ( raycaster.params.Line2 !== undefined ) ? raycaster.params.Line2.threshold || 0 : 0;
-
-		_ray = raycaster.ray;
-
-		const matrixWorld = this.matrixWorld;
-		const geometry = this.geometry;
-		const material = this.material;
-
-		_lineWidth = material.lineWidth + threshold;
-
-		_instanceStart = geometry.attributes.instanceStart;
-		_instanceEnd = geometry.attributes.instanceEnd;
-
-		// check if we intersect the sphere bounds
-		if ( geometry.boundingSphere === null ) {
-
-			geometry.computeBoundingSphere();
-
-		}
-
-		_sphere.copy( geometry.boundingSphere ).applyMatrix4( matrixWorld );
-
-		// increase the sphere bounds by the worst case line screen space width
-		let sphereMargin;
-		if ( worldUnits ) {
-
-			sphereMargin = _lineWidth * 0.5;
-
-		} else {
-
-			const distanceToSphere = Math.max( camera.near, _sphere.distanceToPoint( _ray.origin ) );
-			sphereMargin = getWorldSpaceHalfWidth( camera, distanceToSphere, material.resolution );
-
-		}
-
-		_sphere.radius += sphereMargin;
-
-		if ( _ray.intersectsSphere( _sphere ) === false ) {
-
-			return;
-
-		}
-
-		// check if we intersect the box bounds
-		if ( geometry.boundingBox === null ) {
-
-			geometry.computeBoundingBox();
-
-		}
-
-		_box.copy( geometry.boundingBox ).applyMatrix4( matrixWorld );
-
-		// increase the box bounds by the worst case line width
-		let boxMargin;
-		if ( worldUnits ) {
-
-			boxMargin = _lineWidth * 0.5;
-
-		} else {
-
-			const distanceToBox = Math.max( camera.near, _box.distanceToPoint( _ray.origin ) );
-			boxMargin = getWorldSpaceHalfWidth( camera, distanceToBox, material.resolution );
-
-		}
-
-		_box.expandByScalar( boxMargin );
-
-		if ( _ray.intersectsBox( _box ) === false ) {
-
-			return;
-
-		}
-
-		if ( worldUnits ) {
-
-			raycastWorldUnits( this, intersects );
-
-		} else {
-
-			raycastScreenSpace( this, camera, intersects );
-
-		}
-
-	}
-
-}
+} );
 
 export { LineSegments2 };

+ 95 - 76
libs/three.js/lines/LineSegmentsGeometry.js

@@ -9,33 +9,32 @@ import {
 	WireframeGeometry
 } from '../build/three.module.js';
 
-const _box = new Box3();
-const _vector = new Vector3();
+var LineSegmentsGeometry = function () {
 
-class LineSegmentsGeometry extends InstancedBufferGeometry {
+	InstancedBufferGeometry.call( this );
 
-	constructor() {
+	this.type = 'LineSegmentsGeometry';
 
-		super();
+	var positions = [ - 1, 2, 0, 1, 2, 0, - 1, 1, 0, 1, 1, 0, - 1, 0, 0, 1, 0, 0, - 1, - 1, 0, 1, - 1, 0 ];
+	var uvs = [ - 1, 2, 1, 2, - 1, 1, 1, 1, - 1, - 1, 1, - 1, - 1, - 2, 1, - 2 ];
+	var index = [ 0, 2, 1, 2, 3, 1, 2, 4, 3, 4, 5, 3, 4, 6, 5, 6, 7, 5 ];
 
-		this.isLineSegmentsGeometry = true;
+	this.setIndex( index );
+	this.setAttribute( 'position', new Float32BufferAttribute( positions, 3 ) );
+	this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
 
-		this.type = 'LineSegmentsGeometry';
+};
 
-		const positions = [ - 1, 2, 0, 1, 2, 0, - 1, 1, 0, 1, 1, 0, - 1, 0, 0, 1, 0, 0, - 1, - 1, 0, 1, - 1, 0 ];
-		const uvs = [ - 1, 2, 1, 2, - 1, 1, 1, 1, - 1, - 1, 1, - 1, - 1, - 2, 1, - 2 ];
-		const index = [ 0, 2, 1, 2, 3, 1, 2, 4, 3, 4, 5, 3, 4, 6, 5, 6, 7, 5 ];
+LineSegmentsGeometry.prototype = Object.assign( Object.create( InstancedBufferGeometry.prototype ), {
 
-		this.setIndex( index );
-		this.setAttribute( 'position', new Float32BufferAttribute( positions, 3 ) );
-		this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
+	constructor: LineSegmentsGeometry,
 
-	}
+	isLineSegmentsGeometry: true,
 
-	applyMatrix4( matrix ) {
+	applyMatrix4: function ( matrix ) {
 
-		const start = this.attributes.instanceStart;
-		const end = this.attributes.instanceEnd;
+		var start = this.attributes.instanceStart;
+		var end = this.attributes.instanceEnd;
 
 		if ( start !== undefined ) {
 
@@ -61,11 +60,11 @@ class LineSegmentsGeometry extends InstancedBufferGeometry {
 
 		return this;
 
-	}
+	},
 
-	setPositions( array ) {
+	setPositions: function ( array ) {
 
-		let lineSegments;
+		var lineSegments;
 
 		if ( array instanceof Float32Array ) {
 
@@ -77,7 +76,7 @@ class LineSegmentsGeometry extends InstancedBufferGeometry {
 
 		}
 
-		const instanceBuffer = new InstancedInterleavedBuffer( lineSegments, 6, 1 ); // xyz, xyz
+		var instanceBuffer = new InstancedInterleavedBuffer( lineSegments, 6, 1 ); // xyz, xyz
 
 		this.setAttribute( 'instanceStart', new InterleavedBufferAttribute( instanceBuffer, 3, 0 ) ); // xyz
 		this.setAttribute( 'instanceEnd', new InterleavedBufferAttribute( instanceBuffer, 3, 3 ) ); // xyz
@@ -89,11 +88,11 @@ class LineSegmentsGeometry extends InstancedBufferGeometry {
 
 		return this;
 
-	}
+	},
 
-	setColors( array ) {
+	setColors: function ( array ) {
 
-		let colors;
+		var colors;
 
 		if ( array instanceof Float32Array ) {
 
@@ -105,32 +104,32 @@ class LineSegmentsGeometry extends InstancedBufferGeometry {
 
 		}
 
-		const instanceColorBuffer = new InstancedInterleavedBuffer( colors, 6, 1 ); // rgb, rgb
+		var instanceColorBuffer = new InstancedInterleavedBuffer( colors, 6, 1 ); // rgb, rgb
 
 		this.setAttribute( 'instanceColorStart', new InterleavedBufferAttribute( instanceColorBuffer, 3, 0 ) ); // rgb
 		this.setAttribute( 'instanceColorEnd', new InterleavedBufferAttribute( instanceColorBuffer, 3, 3 ) ); // rgb
 
 		return this;
 
-	}
+	},
 
-	fromWireframeGeometry( geometry ) {
+	fromWireframeGeometry: function ( geometry ) {
 
 		this.setPositions( geometry.attributes.position.array );
 
 		return this;
 
-	}
+	},
 
-	fromEdgesGeometry( geometry ) {
+	fromEdgesGeometry: function ( geometry ) {
 
 		this.setPositions( geometry.attributes.position.array );
 
 		return this;
 
-	}
+	},
 
-	fromMesh( mesh ) {
+	fromMesh: function ( mesh ) {
 
 		this.fromWireframeGeometry( new WireframeGeometry( mesh.geometry ) );
 
@@ -138,97 +137,117 @@ class LineSegmentsGeometry extends InstancedBufferGeometry {
 
 		return this;
 
-	}
+	},
+
+	fromLineSegments: function ( lineSegments ) {
+
+		var geometry = lineSegments.geometry;
 
-	fromLineSegments( lineSegments ) {
+		if ( geometry.isGeometry ) {
 
-		const geometry = lineSegments.geometry;
+			this.setPositions( geometry.vertices );
 
-		this.setPositions( geometry.attributes.position.array ); // assumes non-indexed
+		} else if ( geometry.isBufferGeometry ) {
+
+			this.setPositions( geometry.attributes.position.array ); // assumes non-indexed
+
+		}
 
 		// set colors, maybe
 
 		return this;
 
-	}
+	},
 
-	computeBoundingBox() {
+	computeBoundingBox: function () {
 
-		if ( this.boundingBox === null ) {
+		var box = new Box3();
 
-			this.boundingBox = new Box3();
+		return function computeBoundingBox() {
 
-		}
+			if ( this.boundingBox === null ) {
 
-		const start = this.attributes.instanceStart;
-		const end = this.attributes.instanceEnd;
+				this.boundingBox = new Box3();
 
-		if ( start !== undefined && end !== undefined ) {
+			}
 
-			this.boundingBox.setFromBufferAttribute( start );
+			var start = this.attributes.instanceStart;
+			var end = this.attributes.instanceEnd;
 
-			_box.setFromBufferAttribute( end );
+			if ( start !== undefined && end !== undefined ) {
 
-			this.boundingBox.union( _box );
+				this.boundingBox.setFromBufferAttribute( start );
 
-		}
+				box.setFromBufferAttribute( end );
 
-	}
+				this.boundingBox.union( box );
 
-	computeBoundingSphere() {
+			}
 
-		if ( this.boundingSphere === null ) {
+		};
 
-			this.boundingSphere = new Sphere();
+	}(),
 
-		}
+	computeBoundingSphere: function () {
 
-		if ( this.boundingBox === null ) {
+		var vector = new Vector3();
 
-			this.computeBoundingBox();
+		return function computeBoundingSphere() {
 
-		}
+			if ( this.boundingSphere === null ) {
 
-		const start = this.attributes.instanceStart;
-		const end = this.attributes.instanceEnd;
+				this.boundingSphere = new Sphere();
 
-		if ( start !== undefined && end !== undefined ) {
+			}
+
+			if ( this.boundingBox === null ) {
 
-			const center = this.boundingSphere.center;
+				this.computeBoundingBox();
 
-			this.boundingBox.getCenter( center );
+			}
 
-			let maxRadiusSq = 0;
+			var start = this.attributes.instanceStart;
+			var end = this.attributes.instanceEnd;
 
-			for ( let i = 0, il = start.count; i < il; i ++ ) {
+			if ( start !== undefined && end !== undefined ) {
 
-				_vector.fromBufferAttribute( start, i );
-				maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( _vector ) );
+				var center = this.boundingSphere.center;
 
-				_vector.fromBufferAttribute( end, i );
-				maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( _vector ) );
+				this.boundingBox.getCenter( center );
 
-			}
+				var maxRadiusSq = 0;
 
-			this.boundingSphere.radius = Math.sqrt( maxRadiusSq );
+				for ( var i = 0, il = start.count; i < il; i ++ ) {
 
-			if ( isNaN( this.boundingSphere.radius ) ) {
+					vector.fromBufferAttribute( start, i );
+					maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( vector ) );
 
-				console.error( 'THREE.LineSegmentsGeometry.computeBoundingSphere(): Computed radius is NaN. The instanced position data is likely to have NaN values.', this );
+					vector.fromBufferAttribute( end, i );
+					maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( vector ) );
+
+				}
+
+				this.boundingSphere.radius = Math.sqrt( maxRadiusSq );
+
+				if ( isNaN( this.boundingSphere.radius ) ) {
+
+					console.error( 'THREE.LineSegmentsGeometry.computeBoundingSphere(): Computed radius is NaN. The instanced position data is likely to have NaN values.', this );
+
+				}
 
 			}
 
-		}
+		};
 
-	}
+	}(),
 
-	toJSON() {
+	toJSON: function () {
 
 		// todo
 
-	}
+	},
 
-	applyMatrix( matrix ) {
+	applyMatrix: function ( matrix ) {
 
 		console.warn( 'THREE.LineSegmentsGeometry: applyMatrix() has been renamed to applyMatrix4().' );
 
@@ -236,6 +255,6 @@ class LineSegmentsGeometry extends InstancedBufferGeometry {
 
 	}
 
-}
+} );
 
 export { LineSegmentsGeometry };

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

@@ -5,7 +5,7 @@ import {
 	RGBA_S3TC_DXT5_Format,
 	RGB_ETC1_Format,
 	RGB_S3TC_DXT1_Format
-} from '../build/three.module.js';
+} from '../../../build/three.module.js';
 
 var DDSLoader = function ( manager ) {
 

+ 170 - 117
libs/three.js/loaders/DRACOLoader.js

@@ -3,68 +3,89 @@ import {
 	BufferGeometry,
 	FileLoader,
 	Loader
-} from '../build/three.module.js';
+} from '../../../build/three.module.js';
 
-const _taskCache = new WeakMap();
+var DRACOLoader = function ( manager ) {
 
-class DRACOLoader extends Loader {
+	Loader.call( this, manager );
 
-	constructor( manager ) {
+	this.decoderPath = '';
+	this.decoderConfig = {};
+	this.decoderBinary = null;
+	this.decoderPending = null;
 
-		super( manager );
+	this.workerLimit = 4;
+	this.workerPool = [];
+	this.workerNextTaskID = 1;
+	this.workerSourceURL = '';
 
-		this.decoderPath = '';
-		this.decoderConfig = {};
-		this.decoderBinary = null;
-		this.decoderPending = null;
+	this.defaultAttributeIDs = {
+		position: 'POSITION',
+		normal: 'NORMAL',
+		color: 'COLOR',
+		uv: 'TEX_COORD'
+	};
+	this.defaultAttributeTypes = {
+		position: 'Float32Array',
+		normal: 'Float32Array',
+		color: 'Float32Array',
+		uv: 'Float32Array'
+	};
 
-		this.workerLimit = 4;
-		this.workerPool = [];
-		this.workerNextTaskID = 1;
-		this.workerSourceURL = '';
+};
 
-		this.defaultAttributeIDs = {
-			position: 'POSITION',
-			normal: 'NORMAL',
-			color: 'COLOR',
-			uv: 'TEX_COORD'
-		};
-		this.defaultAttributeTypes = {
-			position: 'Float32Array',
-			normal: 'Float32Array',
-			color: 'Float32Array',
-			uv: 'Float32Array'
-		};
+DRACOLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
 
-	}
+	constructor: DRACOLoader,
 
-	setDecoderPath( path ) {
+	setDecoderPath: function ( path ) {
 
 		this.decoderPath = path;
 
 		return this;
 
-	}
+	},
 
-	setDecoderConfig( config ) {
+	setDecoderConfig: function ( config ) {
 
 		this.decoderConfig = config;
 
 		return this;
 
-	}
+	},
 
-	setWorkerLimit( workerLimit ) {
+	setWorkerLimit: function ( workerLimit ) {
 
 		this.workerLimit = workerLimit;
 
 		return this;
 
-	}
+	},
+
+	/** @deprecated */
+	setVerbosity: function () {
+
+		console.warn( 'THREE.DRACOLoader: The .setVerbosity() method has been removed.' );
+
+	},
 
-	load( url, onLoad, onProgress, onError ) {
+	/** @deprecated */
+	setDrawMode: function () {
 
-		const loader = new FileLoader( this.manager );
+		console.warn( 'THREE.DRACOLoader: The .setDrawMode() method has been removed.' );
+
+	},
+
+	/** @deprecated */
+	setSkipDequantization: function () {
+
+		console.warn( 'THREE.DRACOLoader: The .setSkipDequantization() method has been removed.' );
+
+	},
+
+	load: function ( url, onLoad, onProgress, onError ) {
+
+		var loader = new FileLoader( this.manager );
 
 		loader.setPath( this.path );
 		loader.setResponseType( 'arraybuffer' );
@@ -73,7 +94,7 @@ class DRACOLoader extends Loader {
 
 		loader.load( url, ( buffer ) => {
 
-			const taskConfig = {
+			var taskConfig = {
 				attributeIDs: this.defaultAttributeIDs,
 				attributeTypes: this.defaultAttributeTypes,
 				useUniqueIDs: false
@@ -85,12 +106,12 @@ class DRACOLoader extends Loader {
 
 		}, onProgress, onError );
 
-	}
+	},
 
 	/** @deprecated Kept for backward-compatibility with previous DRACOLoader versions. */
-	decodeDracoFile( buffer, callback, attributeIDs, attributeTypes ) {
+	decodeDracoFile: function ( buffer, callback, attributeIDs, attributeTypes ) {
 
-		const taskConfig = {
+		var taskConfig = {
 			attributeIDs: attributeIDs || this.defaultAttributeIDs,
 			attributeTypes: attributeTypes || this.defaultAttributeTypes,
 			useUniqueIDs: !! attributeIDs
@@ -98,16 +119,16 @@ class DRACOLoader extends Loader {
 
 		this.decodeGeometry( buffer, taskConfig ).then( callback );
 
-	}
+	},
 
-	decodeGeometry( buffer, taskConfig ) {
+	decodeGeometry: function ( buffer, taskConfig ) {
 
 		// TODO: For backward-compatibility, support 'attributeTypes' objects containing
 		// references (rather than names) to typed array constructors. These must be
 		// serialized before sending them to the worker.
-		for ( const attribute in taskConfig.attributeTypes ) {
+		for ( var attribute in taskConfig.attributeTypes ) {
 
-			const type = taskConfig.attributeTypes[ attribute ];
+			var type = taskConfig.attributeTypes[ attribute ];
 
 			if ( type.BYTES_PER_ELEMENT !== undefined ) {
 
@@ -119,13 +140,13 @@ class DRACOLoader extends Loader {
 
 		//
 
-		const taskKey = JSON.stringify( taskConfig );
+		var taskKey = JSON.stringify( taskConfig );
 
 		// Check for an existing task using this buffer. A transferred buffer cannot be transferred
 		// again from this thread.
-		if ( _taskCache.has( buffer ) ) {
+		if ( DRACOLoader.taskCache.has( buffer ) ) {
 
-			const cachedTask = _taskCache.get( buffer );
+			var cachedTask = DRACOLoader.taskCache.get( buffer );
 
 			if ( cachedTask.key === taskKey ) {
 
@@ -150,13 +171,13 @@ class DRACOLoader extends Loader {
 
 		//
 
-		let worker;
-		const taskID = this.workerNextTaskID ++;
-		const taskCost = buffer.byteLength;
+		var worker;
+		var taskID = this.workerNextTaskID ++;
+		var taskCost = buffer.byteLength;
 
 		// Obtain a worker and assign a task, and construct a geometry instance
 		// when the task completes.
-		const geometryPending = this._getWorker( taskID, taskCost )
+		var geometryPending = this._getWorker( taskID, taskCost )
 			.then( ( _worker ) => {
 
 				worker = _worker;
@@ -191,7 +212,7 @@ class DRACOLoader extends Loader {
 			} );
 
 		// Cache the task result.
-		_taskCache.set( buffer, {
+		DRACOLoader.taskCache.set( buffer, {
 
 			key: taskKey,
 			promise: geometryPending
@@ -200,11 +221,11 @@ class DRACOLoader extends Loader {
 
 		return geometryPending;
 
-	}
+	},
 
-	_createGeometry( geometryData ) {
+	_createGeometry: function ( geometryData ) {
 
-		const geometry = new BufferGeometry();
+		var geometry = new BufferGeometry();
 
 		if ( geometryData.index ) {
 
@@ -212,12 +233,12 @@ class DRACOLoader extends Loader {
 
 		}
 
-		for ( let i = 0; i < geometryData.attributes.length; i ++ ) {
+		for ( var i = 0; i < geometryData.attributes.length; i ++ ) {
 
-			const attribute = geometryData.attributes[ i ];
-			const name = attribute.name;
-			const array = attribute.array;
-			const itemSize = attribute.itemSize;
+			var attribute = geometryData.attributes[ i ];
+			var name = attribute.name;
+			var array = attribute.array;
+			var itemSize = attribute.itemSize;
 
 			geometry.setAttribute( name, new BufferAttribute( array, itemSize ) );
 
@@ -225,11 +246,11 @@ class DRACOLoader extends Loader {
 
 		return geometry;
 
-	}
+	},
 
-	_loadLibrary( url, responseType ) {
+	_loadLibrary: function ( url, responseType ) {
 
-		const loader = new FileLoader( this.manager );
+		var loader = new FileLoader( this.manager );
 		loader.setPath( this.decoderPath );
 		loader.setResponseType( responseType );
 		loader.setWithCredentials( this.withCredentials );
@@ -240,22 +261,22 @@ class DRACOLoader extends Loader {
 
 		} );
 
-	}
+	},
 
-	preload() {
+	preload: function () {
 
 		this._initDecoder();
 
 		return this;
 
-	}
+	},
 
-	_initDecoder() {
+	_initDecoder: function () {
 
 		if ( this.decoderPending ) return this.decoderPending;
 
-		const useJS = typeof WebAssembly !== 'object' || this.decoderConfig.type === 'js';
-		const librariesPending = [];
+		var useJS = typeof WebAssembly !== 'object' || this.decoderConfig.type === 'js';
+		var librariesPending = [];
 
 		if ( useJS ) {
 
@@ -271,7 +292,7 @@ class DRACOLoader extends Loader {
 		this.decoderPending = Promise.all( librariesPending )
 			.then( ( libraries ) => {
 
-				const jsContent = libraries[ 0 ];
+				var jsContent = libraries[ 0 ];
 
 				if ( ! useJS ) {
 
@@ -279,9 +300,9 @@ class DRACOLoader extends Loader {
 
 				}
 
-				const fn = DRACOWorker.toString();
+				var fn = DRACOLoader.DRACOWorker.toString();
 
-				const body = [
+				var body = [
 					'/* draco decoder */',
 					jsContent,
 					'',
@@ -295,15 +316,15 @@ class DRACOLoader extends Loader {
 
 		return this.decoderPending;
 
-	}
+	},
 
-	_getWorker( taskID, taskCost ) {
+	_getWorker: function ( taskID, taskCost ) {
 
 		return this._initDecoder().then( () => {
 
 			if ( this.workerPool.length < this.workerLimit ) {
 
-				const worker = new Worker( this.workerSourceURL );
+				var worker = new Worker( this.workerSourceURL );
 
 				worker._callbacks = {};
 				worker._taskCosts = {};
@@ -313,7 +334,7 @@ class DRACOLoader extends Loader {
 
 				worker.onmessage = function ( e ) {
 
-					const message = e.data;
+					var message = e.data;
 
 					switch ( message.type ) {
 
@@ -344,32 +365,32 @@ class DRACOLoader extends Loader {
 
 			}
 
-			const worker = this.workerPool[ this.workerPool.length - 1 ];
+			var worker = this.workerPool[ this.workerPool.length - 1 ];
 			worker._taskCosts[ taskID ] = taskCost;
 			worker._taskLoad += taskCost;
 			return worker;
 
 		} );
 
-	}
+	},
 
-	_releaseTask( worker, taskID ) {
+	_releaseTask: function ( worker, taskID ) {
 
 		worker._taskLoad -= worker._taskCosts[ taskID ];
 		delete worker._callbacks[ taskID ];
 		delete worker._taskCosts[ taskID ];
 
-	}
+	},
 
-	debug() {
+	debug: function () {
 
 		console.log( 'Task load: ', this.workerPool.map( ( worker ) => worker._taskLoad ) );
 
-	}
+	},
 
-	dispose() {
+	dispose: function () {
 
-		for ( let i = 0; i < this.workerPool.length; ++ i ) {
+		for ( var i = 0; i < this.workerPool.length; ++ i ) {
 
 			this.workerPool[ i ].terminate();
 
@@ -381,18 +402,18 @@ class DRACOLoader extends Loader {
 
 	}
 
-}
+} );
 
 /* WEB WORKER */
 
-function DRACOWorker() {
+DRACOLoader.DRACOWorker = function () {
 
-	let decoderConfig;
-	let decoderPending;
+	var decoderConfig;
+	var decoderPending;
 
 	onmessage = function ( e ) {
 
-		const message = e.data;
+		var message = e.data;
 
 		switch ( message.type ) {
 
@@ -413,20 +434,20 @@ function DRACOWorker() {
 				break;
 
 			case 'decode':
-				const buffer = message.buffer;
-				const taskConfig = message.taskConfig;
+				var buffer = message.buffer;
+				var taskConfig = message.taskConfig;
 				decoderPending.then( ( module ) => {
 
-					const draco = module.draco;
-					const decoder = new draco.Decoder();
-					const decoderBuffer = new draco.DecoderBuffer();
+					var draco = module.draco;
+					var decoder = new draco.Decoder();
+					var decoderBuffer = new draco.DecoderBuffer();
 					decoderBuffer.Init( new Int8Array( buffer ), buffer.byteLength );
 
 					try {
 
-						const geometry = decodeGeometry( draco, decoder, decoderBuffer, taskConfig );
+						var geometry = decodeGeometry( draco, decoder, decoderBuffer, taskConfig );
 
-						const buffers = geometry.attributes.map( ( attr ) => attr.array.buffer );
+						var buffers = geometry.attributes.map( ( attr ) => attr.array.buffer );
 
 						if ( geometry.index ) buffers.push( geometry.index.array.buffer );
 
@@ -454,13 +475,13 @@ function DRACOWorker() {
 
 	function decodeGeometry( draco, decoder, decoderBuffer, taskConfig ) {
 
-		const attributeIDs = taskConfig.attributeIDs;
-		const attributeTypes = taskConfig.attributeTypes;
+		var attributeIDs = taskConfig.attributeIDs;
+		var attributeTypes = taskConfig.attributeTypes;
 
-		let dracoGeometry;
-		let decodingStatus;
+		var dracoGeometry;
+		var decodingStatus;
 
-		const geometryType = decoder.GetEncodedGeometryType( decoderBuffer );
+		var geometryType = decoder.GetEncodedGeometryType( decoderBuffer );
 
 		if ( geometryType === draco.TRIANGULAR_MESH ) {
 
@@ -484,15 +505,15 @@ function DRACOWorker() {
 
 		}
 
-		const geometry = { index: null, attributes: [] };
+		var geometry = { index: null, attributes: [] };
 
 		// Gather all vertex attributes.
-		for ( const attributeName in attributeIDs ) {
+		for ( var attributeName in attributeIDs ) {
 
-			const attributeType = self[ attributeTypes[ attributeName ] ];
+			var attributeType = self[ attributeTypes[ attributeName ] ];
 
-			let attribute;
-			let attributeID;
+			var attribute;
+			var attributeID;
 
 			// A Draco file may be created with default vertex attributes, whose attribute IDs
 			// are mapped 1:1 from their semantic name (POSITION, NORMAL, ...). Alternatively,
@@ -532,13 +553,13 @@ function DRACOWorker() {
 
 	function decodeIndex( draco, decoder, dracoGeometry ) {
 
-		const numFaces = dracoGeometry.num_faces();
-		const numIndices = numFaces * 3;
-		const byteLength = numIndices * 4;
+		var numFaces = dracoGeometry.num_faces();
+		var numIndices = numFaces * 3;
+		var byteLength = numIndices * 4;
 
-		const ptr = draco._malloc( byteLength );
+		var ptr = draco._malloc( byteLength );
 		decoder.GetTrianglesUInt32Array( dracoGeometry, byteLength, ptr );
-		const index = new Uint32Array( draco.HEAPF32.buffer, ptr, numIndices ).slice();
+		var index = new Uint32Array( draco.HEAPF32.buffer, ptr, numIndices ).slice();
 		draco._free( ptr );
 
 		return { array: index, itemSize: 1 };
@@ -547,15 +568,15 @@ function DRACOWorker() {
 
 	function decodeAttribute( draco, decoder, dracoGeometry, attributeName, attributeType, attribute ) {
 
-		const numComponents = attribute.num_components();
-		const numPoints = dracoGeometry.num_points();
-		const numValues = numPoints * numComponents;
-		const byteLength = numValues * attributeType.BYTES_PER_ELEMENT;
-		const dataType = getDracoDataType( draco, attributeType );
+		var numComponents = attribute.num_components();
+		var numPoints = dracoGeometry.num_points();
+		var numValues = numPoints * numComponents;
+		var byteLength = numValues * attributeType.BYTES_PER_ELEMENT;
+		var dataType = getDracoDataType( draco, attributeType );
 
-		const ptr = draco._malloc( byteLength );
+		var ptr = draco._malloc( byteLength );
 		decoder.GetAttributeDataArrayForAllPoints( dracoGeometry, attribute, dataType, byteLength, ptr );
-		const array = new attributeType( draco.HEAPF32.buffer, ptr, numValues ).slice();
+		var array = new attributeType( draco.HEAPF32.buffer, ptr, numValues ).slice();
 		draco._free( ptr );
 
 		return {
@@ -582,6 +603,38 @@ function DRACOWorker() {
 
 	}
 
-}
+};
+
+DRACOLoader.taskCache = new WeakMap();
+
+/** Deprecated static methods */
+
+/** @deprecated */
+DRACOLoader.setDecoderPath = function () {
+
+	console.warn( 'THREE.DRACOLoader: The .setDecoderPath() method has been removed. Use instance methods.' );
+
+};
+
+/** @deprecated */
+DRACOLoader.setDecoderConfig = function () {
+
+	console.warn( 'THREE.DRACOLoader: The .setDecoderConfig() method has been removed. Use instance methods.' );
+
+};
+
+/** @deprecated */
+DRACOLoader.releaseDecoderModule = function () {
+
+	console.warn( 'THREE.DRACOLoader: The .releaseDecoderModule() method has been removed. Use instance methods.' );
+
+};
+
+/** @deprecated */
+DRACOLoader.getDecoderModule = function () {
+
+	console.warn( 'THREE.DRACOLoader: The .getDecoderModule() method has been removed. Use instance methods.' );
+
+};
 
 export { DRACOLoader };

+ 35 - 92
libs/three.js/loaders/GLTFLoader.js

@@ -62,38 +62,17 @@ import {
 	VectorKeyframeTrack,
 	sRGBEncoding
 } from '../build/three.module.js';
- 
-
-import {DRACOLoader} from './DRACOLoader.js'
-import {KTX2Loader} from './KTX2Loader.js'
-import { MeshoptDecoder } from '../libs/meshopt_decoder.module.js';
-import {DDSLoader} from './DDSLoader.js'
-
-
 
 var GLTFLoader = ( function () {
 
-	function GLTFLoader( manager, renderer, urlPrefix) {
- 
+	function GLTFLoader( manager ) {
+
 		Loader.call( this, manager );
 
-		/* this.dracoLoader = null;
+		this.dracoLoader = null;
 		this.ddsLoader = null;
 		this.ktx2Loader = null;
-		this.meshoptDecoder = null; */
-        
-        //xzw add:
-        this.dracoLoader = new DRACOLoader;
-        this.ktx2Loader = new KTX2Loader
-        this.meshoptDecoder = MeshoptDecoder;
-        this.ddsLoader = new DDSLoader //这个没测过
-        
-        //路径相对于index.html  
-        this.dracoLoader.setDecoderPath( urlPrefix + 'three.js/loaders/draco/'  /*or 'https://unpkg.com/three@0.144.0/examples/js/libs/draco/gltf/' 版本可升级 */) //这两个路径可以自己改。在laser的环境也要放一份这个路径
-        this.ktx2Loader.setTranscoderPath(urlPrefix + 'three.js/loaders/ktx/' /*or 'https://unpkg.com/three@0.144.0/examples/js/libs/basis/' 版本可升级  */).detectSupport( renderer )
-            
-        //------------
-
+		this.meshoptDecoder = null;
 
 		this.pluginCallbacks = [];
 
@@ -139,7 +118,7 @@ var GLTFLoader = ( function () {
 
 		constructor: GLTFLoader,
 
-		load: function ( url, onLoad, onProgress, onError   ) {
+		load: function ( url, onLoad, onProgress, onError ) {
 
 			var scope = this;
 
@@ -188,27 +167,23 @@ var GLTFLoader = ( function () {
 			loader.setRequestHeader( this.requestHeader );
 			loader.setWithCredentials( this.withCredentials );
 
-			loader.load( url, function ( data, total ) {// xzw add total 
-                console.log('数据加载成功', url.split('/').pop(), '  ,total: '+total)
-                let f = ()=>{
-                    try {
+			loader.load( url, function ( data ) {
 
-                        scope.parse( data, resourcePath, function ( gltf ) {
+				try {
 
-                            onLoad( gltf, total );
+					scope.parse( data, resourcePath, function ( gltf ) {
 
-                            scope.manager.itemEnd( url );
+						onLoad( gltf );
 
-                        }, _onError );
+						scope.manager.itemEnd( url );
 
-                    } catch ( e ) {
+					}, _onError );
 
-                        _onError( e );
+				} catch ( e ) {
 
-                    }
-                }
-                f()
-                //setTimeout(f,5000)/////////////////test
+					_onError( e );
+
+				}
 
 			}, onProgress, _onError );
 
@@ -318,9 +293,10 @@ var GLTFLoader = ( function () {
 				crossOrigin: this.crossOrigin,
 				manager: this.manager,
 				ktx2Loader: this.ktx2Loader,
-				meshoptDecoder: this.meshoptDecoder, 
+				meshoptDecoder: this.meshoptDecoder
+
 			} );
-            parser.unlitMat = this.unlitMat//add
+
 			parser.fileLoader.setRequestHeader( this.requestHeader );
 
 			for ( var i = 0; i < this.pluginCallbacks.length; i ++ ) {
@@ -353,7 +329,7 @@ var GLTFLoader = ( function () {
 							extensions[ extensionName ] = new GLTFMaterialsPbrSpecularGlossinessExtension();
 							break;
 
-						case EXTENSIONS.KHR_DRACO_MESH_COMPRESSION: 
+						case EXTENSIONS.KHR_DRACO_MESH_COMPRESSION:
 							extensions[ extensionName ] = new GLTFDracoMeshCompressionExtension( json, this.dracoLoader );
 							break;
 
@@ -1033,7 +1009,7 @@ var GLTFLoader = ( function () {
 	function GLTFDracoMeshCompressionExtension( json, dracoLoader ) {
 
 		if ( ! dracoLoader ) {
-                
+
 			throw new Error( 'THREE.GLTFLoader: No DRACOLoader instance provided.' );
 
 		}
@@ -1934,17 +1910,15 @@ var GLTFLoader = ( function () {
 
 		// Use an ImageBitmapLoader if imageBitmaps are supported. Moves much of the
 		// expensive work of uploading a texture to the GPU off the main thread.
-		/* if ( typeof createImageBitmap !== 'undefined' && /Firefox/.test( navigator.userAgent ) === false ) {
+		if ( typeof createImageBitmap !== 'undefined' && /Firefox/.test( navigator.userAgent ) === false ) {
 
 			this.textureLoader = new ImageBitmapLoader( this.options.manager );
 
-		} else { */
-        //为了防止chrome出现报错  The source image could not be decoded. 导致reject,改用TextureLoader  by xzw
+		} else {
 
 			this.textureLoader = new TextureLoader( this.options.manager );
 
-		//}
- 
+		}
 
 		this.textureLoader.setCrossOrigin( this.options.crossOrigin );
 
@@ -2491,7 +2465,7 @@ var GLTFLoader = ( function () {
 	};
 
 	GLTFParser.prototype.loadTextureImage = function ( textureIndex, source, loader ) {
-         
+
 		var parser = this;
 		var json = this.json;
 		var options = this.options;
@@ -2538,57 +2512,26 @@ var GLTFLoader = ( function () {
 
 			return new Promise( function ( resolve, reject ) {
 
-				/* var onLoad = resolve;
+				var onLoad = resolve;
+
+				if ( loader.isImageBitmapLoader === true ) {
+
+					onLoad = function ( imageBitmap ) {
 
-				if ( loader.isImageBitmapLoader === true ) { 
-                    onLoad = function ( imageBitmap ) {
-                        //console.log('resolveURL onLoad',textureIndex )
 						resolve( new CanvasTexture( imageBitmap ) );
 
 					};
+
 				}
-                */
-
-                //为了防止chrome出现报错  The source image could not be decoded. 导致reject,重新写贴图加载方式:
-
-                parser.textureLoader.load(sourceURI, (tex)=>{
-                    tex.minFilter = THREE.LinearMipmapLinearFilter //原本:NearestMipMapNearestFilter 闪烁
-                    //tex.needsUpdate
-                    resolve(tex) 
-                })  
-               
-                return;
-
-				loader.load( resolveURL( sourceURI, options.path ), onLoad, undefined,   (e,url)=>{
-                    console.log('reject',textureIndex, arguments)
-                    if ( loader.isImageBitmapLoader === true ) {
-                        let img = new Image;
-                        img.setAttribute('crossOrigin', 'Anonymous')
-                        img.src = url; 
-                        resolve(new THREE.Texture(img))
-                        
-                        
-                        /* img.onload = ()=>{
-                            let canvas = document.createElement('canvas')
-                            let context = canvas.getContext('2d')
-                            context.canvas.width = img.width
-                            context.canvas.height = img.height
-                            context.drawImage(img, 0, 0, img.width, img.height)
-                            resolve( new CanvasTexture( canvas ) );   
-                            console.log('自己绘制 onload', textureIndex)
-                        } */
-                    }else{
-                        reject.apply(this,arguments)
-                    }
-                     
-                }  /*  ,  reject  */  );
+
+				loader.load( resolveURL( sourceURI, options.path ), onLoad, undefined, reject );
 
 			} );
 
 		} ).then( function ( texture ) {
-            
+
 			// Clean up resources and configure Texture.
-            //console.log('texture', textureIndex, texture.image)
+
 			if ( isObjectURL === true ) {
 
 				URL.revokeObjectURL( sourceURI );
@@ -2785,7 +2728,7 @@ var GLTFLoader = ( function () {
 
 	GLTFParser.prototype.getMaterialType = function ( /* materialIndex */ ) {
 
-		return this.unlitMat ? MeshBasicMaterial : MeshStandardMaterial;  //xzw add unlitMat
+		return MeshStandardMaterial;
 
 	};
 

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 499 - 481
libs/three.js/loaders/KTX2Loader.js


+ 8 - 9
libs/three.js/loaders/MTLLoader.js

@@ -5,12 +5,12 @@ import {
 	FrontSide,
 	Loader,
 	LoaderUtils,
-	MeshStandardMaterial,//MeshPhongMaterial, 用MeshStandardMaterial好调些,因为遵循能量守恒
+	MeshPhongMaterial,
 	RepeatWrapping,
 	TextureLoader,
 	Vector2
-} from '../build/three.module.js';
- 
+} from '../../../build/three.module.js';
+
 /**
  * Loads a Wavefront .mtl file specifying materials
  */
@@ -388,8 +388,8 @@ MTLLoader.MaterialCreator.prototype = {
 				case 'ks':
 
 					// Specular color (color when light is reflected from shiny surface) using RGB values
-					//params.specular = new Color().fromArray( value );
-                    //console.log('specular',value)
+					params.specular = new Color().fromArray( value );
+
 					break;
 
 				case 'ke':
@@ -452,9 +452,8 @@ MTLLoader.MaterialCreator.prototype = {
 					// The specular exponent (defines the focus of the specular highlight)
 					// A high exponent results in a tight, concentrated highlight. Ns values normally range from 0 to 1000.
 
-					//params.shininess = parseFloat( value );
-                    //console.log('shininess',value)
-                    
+					params.shininess = parseFloat( value );
+
 					break;
 
 				case 'd':
@@ -490,7 +489,7 @@ MTLLoader.MaterialCreator.prototype = {
 
 		}
 
-		this.materials[ materialName ] = new MeshStandardMaterial( params )//MeshPhongMaterial( params );
+		this.materials[ materialName ] = new MeshPhongMaterial( params );
 		return this.materials[ materialName ];
 
 	},

+ 2 - 2
libs/three.js/loaders/OBJLoader.js

@@ -451,11 +451,11 @@ var OBJLoader = ( function () {
 			loader.setPath( this.path );
 			loader.setRequestHeader( this.requestHeader );
 			loader.setWithCredentials( this.withCredentials );
-			loader.load( url, function ( text , total ) {// xzw add total 
+			loader.load( url, function ( text ) {
 
 				try {
 
-					onLoad( scope.parse( text ) , total );
+					onLoad( scope.parse( text ) );
 
 				} catch ( e ) {
 

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 0 - 52
libs/three.js/loaders/draco/draco_decoder.js


BIN=BIN
libs/three.js/loaders/draco/draco_decoder.wasm


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 0 - 104
libs/three.js/loaders/draco/draco_wasm_wrapper.js


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 0 - 21
libs/three.js/loaders/ktx/basis_transcoder.js


BIN=BIN
libs/three.js/loaders/ktx/basis_transcoder.wasm


BIN=BIN
note/images360.updateCube笔记.jpg


BIN=BIN
resources/textures/explode.png


BIN=BIN
resources/textures/fire.png


BIN=BIN
resources/textures/icon-explode.png


BIN=BIN
resources/textures/icon-fire.png


BIN=BIN
resources/textures/icon-smoke.png


BIN=BIN
resources/textures/pic_point_s32.png


BIN=BIN
resources/textures/smokeparticle.png


+ 3 - 3
src/Actions.js

@@ -1,8 +1,8 @@
 
-import * as THREE from "../libs/three.js/build/three.module.js";
- 
 
-export class Action extends THREE.EventDispatcher {
+import {EventDispatcher} from "./EventDispatcher.js";
+
+export class Action extends EventDispatcher {
 	constructor (args = {}) {
 		super();
 

+ 3 - 2
src/Annotation.js

@@ -2,9 +2,10 @@
 
 import * as THREE from "../libs/three.js/build/three.module.js";
 import {Action} from "./Actions.js";
-import {Utils} from "./utils.js"; 
+import {Utils} from "./utils.js";
+import {EventDispatcher} from "./EventDispatcher.js";
 
-export class Annotation extends THREE.EventDispatcher {
+export class Annotation extends EventDispatcher {
 	constructor (args = {}) {
 		super();
 

+ 6 - 22
src/EventDispatcher.js

@@ -28,9 +28,9 @@
 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 // THE SOFTWARE.
 
- 
 
- 
+
+
 
 export class EventDispatcher{
 
@@ -84,15 +84,9 @@ export class EventDispatcher{
 			delete this._listeners[type];
 		}
 	};
-    
-    
-    
 
 	dispatchEvent(event){
-        if(typeof event == 'string'){//add
-            event = {type:event}
-        }
-        
+
 		let listeners = this._listeners;
 		let listenerArray = listeners[event.type];
 
@@ -111,18 +105,14 @@ export class EventDispatcher{
     
     
     //add 
-    /* emit(type){ 
+    emit(type){ 
         this.dispatchEvent({type, arguments: Array.from(arguments).slice(1, arguments.length) })
     }
-    on(type, fun){  
+    on(type, fun){
         this.addEventListener(type,(ev)=>{
             fun.apply(this, ev.arguments)
         })
-    } 
-    off(type, fun){
-        this.removeEventListener(type,)
-    }
-    
+    }  
     once(type, fun) {
         function callback() {
             this.removeEventListener(type, callback),
@@ -132,12 +122,6 @@ export class EventDispatcher{
         return callback.listener = fun,
             this.on(type, callback),
             this
-    }  */
-    
-    removeAllListeners(){
-        
-        this._listeners = {};
-        
     }
      
 }

+ 0 - 21
src/Features.js

@@ -1,8 +1,4 @@
 
-import browser from './utils/browser.js'
-
-
-
 let ftCanvas = document.createElement('canvas');
 
 export const Features = (function () {
@@ -71,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;

+ 1 - 2
src/KeyCodes.js

@@ -7,8 +7,7 @@ export const KeyCodes = {
 	RIGHT: 39,
 	BOTTOM: 40,
 	DELETE: 46,
-    BACKSPACE:8,
-    
+
 	A: 'A'.charCodeAt(0),
 	S: 'S'.charCodeAt(0),
 	D: 'D'.charCodeAt(0),

+ 1 - 7
src/LRU.js

@@ -147,13 +147,7 @@ class LRU{
 		} */ 
         
         //改成navvis的,使用pointBudget,否则四屏点云闪烁。
-        
-        
-        let max = /* this.pageVisible ?  */viewer.viewports.length * 2 * Potree.pointBudget// : 1000
-        
-        
-        
-        for (; this.numPoints > max;  ) {//要根据屏幕数量来增加pointBudget
+        for (; this.numPoints > viewer.viewports.length * 2 * Potree.pointBudget;  ) {//要根据屏幕数量来增加pointBudget
             var node = this.getLRUItem();
             node && this.disposeSubtree(node)
         }

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 63 - 944
src/PointCloudOctree.js


+ 6 - 6
src/PointCloudOctreeGeometry.js

@@ -1,10 +1,11 @@
- 
+
+import { EventDispatcher } from "./EventDispatcher.js";
 import * as THREE from "../libs/three.js/build/three.module.js";
 import {PointCloudTreeNode} from "./PointCloudTree.js";
 import {XHRFactory} from "./XHRFactory.js";
 import {Utils} from "./utils.js";
 
-export class PointCloudOctreeGeometry extends THREE.EventDispatcher{
+export class PointCloudOctreeGeometry extends EventDispatcher{
 
 	constructor(){
         super()
@@ -92,7 +93,7 @@ export class PointCloudOctreeGeometryNode extends PointCloudTreeNode{
 		} else if (version.upTo('1.3')) {
 			url = this.pcoGeometry.octreeDir + '/' + this.name;
 		}
-       
+
 		return url;
 	}
 
@@ -199,7 +200,7 @@ export class PointCloudOctreeGeometryNode extends PointCloudTreeNode{
 				let parentName = name.substring(0, name.length - 1);
 				let parentNode = nodes[parentName];
 				let level = name.length - 1;
-                pco.dispatchEvent({type:'updateNodeMaxLevel',level});//add
+                pco.emit('updateNodeMaxLevel',level);//add
                 
 				let boundingBox = Utils.createChildAABB(parentNode.boundingBox, index);
 
@@ -223,8 +224,7 @@ export class PointCloudOctreeGeometryNode extends PointCloudTreeNode{
 		if ((node.level % node.pcoGeometry.hierarchyStepSize) === 0) {
 			// let hurl = node.pcoGeometry.octreeDir + "/../hierarchy/" + node.name + ".hrc";
 			let hurl = node.pcoGeometry.octreeDir + '/' + node.getHierarchyPath() + '/' + node.name + '.hrc';
-            hurl += '?m='+node.pcoGeometry.timeStamp //add
-            
+
 			let xhr = XHRFactory.createXMLHttpRequest();
 			xhr.open('GET', hurl, true);
 			xhr.responseType = 'arraybuffer';

+ 4 - 3
src/PointCloudTree.js

@@ -1,7 +1,9 @@
 
-import * as THREE from "../libs/three.js/build/three.module.js"; 
+import * as THREE from "../libs/three.js/build/three.module.js";
+import { EventDispatcher } from "./EventDispatcher.js";
 
-export class PointCloudTreeNode extends THREE.EventDispatcher{
+
+export class PointCloudTreeNode extends EventDispatcher{
 
 	constructor(){
 		super();
@@ -40,7 +42,6 @@ export class PointCloudTreeNode extends THREE.EventDispatcher{
 export class PointCloudTree extends THREE.Object3D {
 	constructor () {
 		super();
-        //this.spriteGroup = new THREE.Object3D  //add
 	}
 
 	initialized () {

+ 55 - 117
src/Potree.js

@@ -1,6 +1,3 @@
-export {config, settings} from "./settings.js";
-export * from "./start.js";
- 
 
 export * from "./Actions.js";
 export * from "./AnimationPath.js";
@@ -19,7 +16,7 @@ export * from "./Points.js";
 export * from "./Potree_update_visibility.js";
 export * from "./PotreeRenderer.js";
 export * from "./ProfileRequest.js";
-//export * from "./TextSprite.js";
+export * from "./TextSprite.js";
 export * from "./utils.js";
 export * from "./Version.js";
 export * from "./WorkerPool.js";
@@ -44,23 +41,23 @@ export * from "./loader/PointAttributes.js";
 export * from "./loader/ShapefileLoader.js";
 export * from "./loader/GeoPackageLoader.js";
 
-export * from "./objects/tool/Box3Helper.js";
-export * from "./objects/tool/ClippingTool.js";
-export * from "./objects/tool/ClipVolume.js";
+export * from "./utils/Box3Helper.js";
+export * from "./utils/ClippingTool.js";
+export * from "./utils/ClipVolume.js";
 export * from "./utils/GeoTIFF.js";
-export * from "./objects/tool/Measure.js";
-export * from "./objects/tool/MeasuringTool.js";
+export * from "./utils/Measure.js";
+export * from "./utils/MeasuringTool.js";
 export * from "./utils/Message.js";
 export * from "./utils/PointCloudSM.js";
-export * from "./objects/tool/PolygonClipVolume.js";
-export * from "./objects/tool/Profile.js";
-export * from "./objects/tool/ProfileTool.js";
-export * from "./objects/tool/ScreenBoxSelectTool.js";
-export * from "./objects/tool/SpotLightHelper.js";
-export * from "./objects/tool/TransformationTool.js";
-export * from "./objects/tool/Volume.js";
-export * from "./objects/tool/VolumeTool.js";
-export * from "./objects/tool/Compass.js";
+export * from "./utils/PolygonClipVolume.js";
+export * from "./utils/Profile.js";
+export * from "./utils/ProfileTool.js";
+export * from "./utils/ScreenBoxSelectTool.js";
+export * from "./utils/SpotLightHelper.js";
+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 "./viewer/Scene.js";
@@ -81,6 +78,8 @@ export {VRControls} from "./navigation/VRControls.js";
 
 //add:
 export {Alignment} from "./modules/datasetAlignment/Alignment.js";
+export {config, settings} from "./settings.js";
+export {start} from "./start.js";
 
 
 
@@ -143,131 +142,73 @@ export {scriptPath, resourcePath};
 
 //add: 
 
- 
 
 
-export async function loadFile(path, callback, onError){
+export async function loadFile(path, callback){
     if(Potree.fileServer){
-         
-        Potree.fileServer.get(path).then(data=>{ 
-            if(data.data)data = data.data
-            if(data.data)data = data.data //融合页面getdataset需要查找两次data
+        Potree.fileServer.get(path).then(data=>{
             callback && callback(data)
-        }).catch(onError) 
+        })
     }else{
-        try{
-            let response = await fetch(path); 
-            let text = await response.text();
-            var data = JSON.parse(text)
-            if(data.data) data = data.data
-            callback && callback(data)    
-            return data 
-        }catch(e){
-            onError && onError(e)
-        }
-          
+        let response = await fetch(path); 
+        let text = await response.text();
+        var data = JSON.parse(text)
+        callback && callback(data) 
+        return data
     }
     
     //查询: http://192.168.0.26:8080/doc.html#/default/filter-%E6%BC%AB%E6%B8%B8%E7%82%B9/filterUsingGET    
 }
 
-export async function loadDatasets(callback,sceneCode,onError){//之后直接把path写进来
-    let path 
-    sceneCode = sceneCode || Potree.settings.number
+export async function loadDatasets(callback){//之后直接把path写进来
+    var path 
     if(Potree.fileServer){
-        path = `/laser/dataset/${sceneCode}/getDataSet` 
+        path = `/laser/dataset/${Potree.settings.number}/getDataSet` 
     }else{
-        
-        //path = `${Potree.settings.urls.prefix2}/indoor/${Potree.settings.number}/api/datasets`
-        //现在只能加载得了本地的了
-        path = `${Potree.settings.urls.prefix}/laser/dataset/${sceneCode}/getDataSet`
-        //path = `${Potree.scriptPath}/data/${sceneCode}/getDataSet.json`
-        
+        path = `https://${Potree.config.urls.prefix2}/indoor/${Potree.settings.number}/api/datasets`
+          
     }
-    return loadFile(path, callback,onError)
+    return loadFile(path, callback)
     
 }
-
-
-//目前上传平面图后如果不点击保存按钮,数据还是旧的不生效
-export async function loadMapEntity(datasetId, force){ 
-    if(!Potree.settings.floorplanEnable && !force && Potree.fileServer  )return /* 等待平面图类型定义好会加载 */
-     
-    
-    let loaded = 0
-    
-    let needLoads = datasetId == 'all' ? viewer.scene.pointclouds.map(e=>e.dataset_id) : [datasetId]
-    
-    
-    let callback = (dataset_id, floorplanType, data  )=>{
-        //要防止旧的比新的先获取到导致覆盖新的,因为两种type随时可能切换
-        if(floorplanType != Potree.settings.floorplanType[dataset_id]) return //如果请求的floorplanType不是当前最新的floorplanType就返回
-        
-        var map = viewer.mapViewer.mapLayer.maps.find(e => e.name == 'floorplan_'+ dataset_id)
-        if(map){  
-            viewer.mapViewer.mapLayer.removeMap(map)
-        } 
-        
-        var mapNew = viewer.mapViewer.mapLayer.addMapEntity(data.data || data,  dataset_id)
+export async function loadMapEntity(){
+    var path 
+    let callback = (data)=>{
+        var map = viewer.mapViewer.mapLayer.maps.find(e => e.name == 'floorplan')
         if(map){
-            mapNew.visibleReasons = map.visibleReasons 
-            mapNew.unvisibleReasons = map.unvisibleReasons 
-        }
-        loaded ++; 
-    } 
-    
-    needLoads.forEach(dataset_id=>{
-        let floorplanType = Potree.settings.floorplanType[dataset_id],  prefix = ''
-        if(!Potree.fileServer){   
-            prefix = Potree.settings.urls.prefix
-        }
-        if(!floorplanType)return
-        var path 
-        /* if(Potree.fileServer){ 
-            path = `/laser/tiledMap/${Potree.settings.number}/tiledMap/${floorplanType}/${dataset_id}` 
+            viewer.mapViewer.mapLayer.removeMap(map)
         }else{
-            path = `${Potree.settings.urls.prefix2}/indoor/${Potree.settings.number}/api/tiled_maps`
             
-        } */
-        path = `${prefix}/laser/tiledMap/${Potree.settings.number}/tiledMap/${floorplanType}/${dataset_id}` 
+        }
         
-        Potree.settings.floorplanRequests[dataset_id] = true //开始加载了
-        return loadFile(path, callback.bind(this,  dataset_id, floorplanType)  )
-    })
-    
+        viewer.mapViewer.mapLayer.addMapEntity(data.data || data )
+    }
+    if(Potree.fileServer){
+        if(!Potree.settings.floorplanType || !Potree.settings.floorplanEnable)return /* 等待平面图类型定义好会加载 */
+        path = `/laser/tiledMap/${Potree.settings.number}/tiledMap/${Potree.settings.floorplanType}` 
+    }else{
+        path = `https://${Potree.config.urls.prefix2}/indoor/${Potree.settings.number}/api/tiled_maps`
+        
+    }
+    return loadFile(path, callback)
      
     
 }
  
-export async function loadPanos(datasetId, callback){
+export async function loadPanos(center, callback){
     var path 
-    let query = `?datasetId=${datasetId}`                  //`?lat=${center.lat}&lon=${center.lon}&radius=200000`
+    let query = ''//`?lat=${center.lat}&lon=${center.lon}&radius=200000`
     if(Potree.fileServer){
         path = `/laser/filter/${Potree.settings.number}/query` + query
-    }else{
-        //path = `${Potree.settings.urls.prefix2}/indoor/${Potree.settings.number}/api/images/filter` + query
-        //path = `${Potree.scriptPath}/data/${Potree.settings.number}/panos-${datasetId}.json`
-        path = `${Potree.settings.urls.prefix}/laser/filter/${Potree.settings.number}/query` + query
-       
-         
+    }else{ 
+        path = `https://${Potree.config.urls.prefix2}/indoor/${Potree.settings.number}/api/images/filter` + query
+             
     }
     return loadFile(path, callback) 
     
 }
 
 
-export async function loadPanosInfo(callback){ 
-    var path 
-    if(Potree.fileServer){
-        
-    }else{
-        path = `${Potree.scriptPath}/data/panoEdit/vision_edit.txt`
-          
-    }
-    return loadFile(path, callback)
-    
-}
-
 
 
 //site_model
@@ -317,7 +258,7 @@ export async function loadPanosInfo(callback){
 
 
 
-export function Log(value, color, fontSize){ 
+export function Log(value, color, fontSize){
     color = color || '#13f'
     fontSize = fontSize || 14
     console.warn(`%c${value}`, `color:${color};font-size:${fontSize}px`) 
@@ -325,11 +266,9 @@ export function Log(value, color, fontSize){
 
  
 
-export function loadPointCloud(path, name, sceneCode, timeStamp, callback, onError){
+export function loadPointCloud(path, name, callback){
 	let loaded = function(e){
 		e.pointcloud.name = name;
-        e.pointcloud.sceneCode = sceneCode //对应4dkk的场景码
-        
 		callback(e);
 	};
 
@@ -350,11 +289,10 @@ export function loadPointCloud(path, name, sceneCode, timeStamp, callback, onErr
 				}
 			});
 		} else if (path.indexOf('cloud.js') > 0) {
-			POCLoader.load(path, timeStamp, function (geometry) {
+			POCLoader.load(path, function (geometry) {
 				if (!geometry) {
 					//callback({type: 'loading_failed'});
 					console.error(new Error(`failed to load point cloud from URL: ${path}`));
-                    onError && onError()
 				} else {
 					let pointcloud = new PointCloudOctree(geometry);
 					// loaded(pointcloud);

+ 16 - 101
src/PotreeRenderer.js

@@ -156,7 +156,7 @@ let attributeLocations = {
 class Shader {
 
 	constructor(gl, name, vsSource, fsSource) {
-		this.gl = gl; 
+		this.gl = gl;
 		this.name = name;
 		this.vsSource = vsSource;
 		this.fsSource = fsSource;
@@ -225,18 +225,11 @@ class Shader {
 
 			this.vs = gl.createShader(gl.VERTEX_SHADER);
 			this.fs = gl.createShader(gl.FRAGMENT_SHADER);
-            
-            
-            
-            
 			this.program = gl.createProgram();
             
             if(  !gl.isProgram(this.program  )){//创建失败  开启多个页面可能会,原因是webglcontextlost
                 //console.error('创建program失败');
-                viewer.dispatchEvent('webglError', {msg: 'potreeRenderer创建program失败'})
-                console.log(this.vs)
-                console.log(this.fs)
-                
+                viewer.emit('webglError', 'potreeRenderer创建program失败')
                 return;
             }
 
@@ -560,7 +553,7 @@ export class Renderer {
 	constructor(threeRenderer) {
 		this.threeRenderer = threeRenderer;
 		this.gl = this.threeRenderer.getContext();
-  
+
 		this.buffers = new Map();
 		this.shaders = new Map();
 		this.textures = new Map();
@@ -691,7 +684,7 @@ export class Renderer {
 
 			let node = stack.pop();
 
-			if (node instanceof PointCloudTree) { 
+			if (node instanceof PointCloudTree) {
 				octrees.push(node);
 				continue;
 			}
@@ -1042,11 +1035,8 @@ export class Renderer {
 			}
 
 			let numPoints = webglBuffer.numElements;
-			 
-            gl.drawArrays(gl.POINTS, 0, numPoints); 
-            //gl.drawArrays(gl.TRIANGLES, 0, numPoints);
-            
-            
+			gl.drawArrays(gl.POINTS, 0, numPoints);
+
 			i++;
 		}
 
@@ -1057,10 +1047,6 @@ export class Renderer {
 			performance.measure("render.renderNodes", "renderNodes-start", "renderNodes-end");
 		}
 	}
-    
-    
-    
-    
 
 	renderOctree(octree, nodes, camera, target, params = {}){
 
@@ -1134,7 +1120,7 @@ export class Renderer {
                 
                 if(material.useFilterByNormal){
                     defines.push("#define use_filter_by_normal");
-                    //Potree.settings.editType == 'pano' ? defines.push("#define attenuated_opacity2") : defines.push("#define attenuated_opacity");
+                    defines.push("#define attenuated_opacity");
                     
                 }
 
@@ -1227,18 +1213,9 @@ export class Renderer {
 
 		if (transparent){
 			gl.enable(gl.BLEND);
-            
-            if(params.notAdditiveBlending){
-                gl.blendFuncSeparate( gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA ); //NormalBlending 
-                gl.enable(gl.DEPTH_TEST);
-                gl.depthMask(true); //如果不开启depthWrite,深度会错乱。 
-            }else{
-                gl.blendFunc(gl.SRC_ALPHA, gl.ONE); //AdditiveBlending   原本
-                gl.disable(gl.DEPTH_TEST);
-                gl.depthMask(false);
-            } 
-			
-			
+			gl.blendFunc(gl.SRC_ALPHA, gl.ONE);
+			gl.depthMask(false);
+			gl.disable(gl.DEPTH_TEST);
 		} else {
 			gl.disable(gl.BLEND);
 			gl.depthMask(true);
@@ -1274,15 +1251,11 @@ export class Renderer {
 			shader.setUniformMatrix4("uViewInv", viewInv);
 			shader.setUniformMatrix4("uProjInv", projInv);
 
-			/* let screenWidth = target ? target.width : material.screenWidth;
+			let screenWidth = target ? target.width : material.screenWidth;
 			let screenHeight = target ? target.height : material.screenHeight;
 
 			shader.setUniform1f("uScreenWidth", screenWidth);
-			shader.setUniform1f("uScreenHeight", screenHeight); */
-            
-            shader.setUniform2f('resolution', material.resolution.toArray())
-            
-            
+			shader.setUniform1f("uScreenHeight", screenHeight);
 			shader.setUniform1f("fov", Math.PI * camera.fov / 180);
 			shader.setUniform1f("near", camera.near);
 			shader.setUniform1f("far", camera.far);
@@ -1343,7 +1316,7 @@ export class Renderer {
 			}
 
 
-			shader.setUniform1f("size", material.usePanoMap ? Potree.config.material.absolutePanoramaSize * Math.min(window.devicePixelRatio,2) : material.size);//usePanoMap时控制在不大不小的范围内感觉较好,考虑到有的点云稀疏,用大一点的点
+			shader.setUniform1f("size", material.usePanoMap ? Potree.config.material.absolutePanoramaSize : material.size);//usePanoMap时控制在不大不小的范围内感觉较好,考虑到有的点云稀疏,用大一点的点
 			shader.setUniform1f("maxSize", material.uniforms.maxSize.value);
 			shader.setUniform1f("minSize", material.uniforms.minSize.value);
 
@@ -1539,37 +1512,10 @@ export class Renderer {
 		gl.activeTexture(gl.TEXTURE2);
 		gl.bindTexture(gl.TEXTURE_2D, null);
 		gl.activeTexture(gl.TEXTURE0);
-        
-        
-        
-        //gl.bindTexture(gl.TEXTURE_2D, null); //add
-        
-        
-        
-        
-        //add  恢复为不透明(否则renderToCubeMap时的贴图会被渲染成高亮的颜色)
-        gl.disable(gl.BLEND);
-        gl.depthMask(true);
-        gl.enable(gl.DEPTH_TEST);
-            //DEPTH_TEST等需要恢复吗
-         
-        
 	}
-    
-    
-    
-    
-    
-    
-    
-    
-    
-    
-    
-
 
 	render(scene, camera, target = null, params = {}) {
- 
+
 		const gl = this.gl;
 
 		// PREPARE 
@@ -1581,42 +1527,11 @@ export class Renderer {
 		// camera.matrixWorldInverse.invert(camera.matrixWorld);
 
 		const traversalResult = this.traverse(scene);
-        
-        //排序
-        if(Potree.settings.notAdditiveBlending){//add 
-            
-            traversalResult.octrees.forEach(tree=>{
-                if(tree.material.opacity==1){
-                    tree._z = Infinity //不透明的先渲染
-                }else{
-                    let center = tree.boundCenter ? tree.boundCenter.clone() : tree.boundingBox.getCenter(tree.boundCenter).applyMatrix4(tree.matrixWorld) 
-                    center.project(camera) 
-                    tree._z = center.z 
-                }
-            })   
-                 
-            traversalResult.octrees.sort((tree1,tree2)=>{ 
-                return tree2._z - tree1._z //降序  (-1 朝外)。 离屏幕近的后渲染
-            })
-        }
-        
-        
-        
-        
+
+
 		// RENDER
 		for (const octree of traversalResult.octrees) {
 			let nodes = octree.visibleNodes;
-            
-            
-            
-            /* nodes.sort((node1,node2)=>{//姑且
-                
-                let center = node.getBoundingSphere().center.clone().applyMatrix4(octree.matrixWorld)
-                return  
-                
-                
-            }) */
-            
 			this.renderOctree(octree, nodes, camera, target, params);
 		}
 

+ 4 - 10
src/Potree_update_visibility.js

@@ -1,7 +1,7 @@
 
 import * as THREE from "../libs/three.js/build/three.module.js";
 import {ClipTask, ClipMethod} from "./defines.js";
-import {Box3Helper} from "./objects/tool/Box3Helper.js";
+import {Box3Helper} from "./utils/Box3Helper.js";
 
 export function updatePointClouds(pointclouds,camera, areaSize /* renderer */){
  
@@ -75,11 +75,8 @@ export function updateVisibilityStructures(pointclouds, camera, areaSize) {
 		let camMatrixObject = new THREE.Matrix4().multiply(worldI).multiply(view);
 		let camObjPos = new THREE.Vector3().setFromMatrixPosition(camMatrixObject);
 		camObjPositions.push(camObjPos);
-        
-        // 因漫游模式而隐藏的话 依旧需要加入visibleNodes,因为pick需要
-        
-                                                    /*  viewer.getObjVisiByReason(pointcloud, 'datasetSelection') */
-		if (pointcloud.visible || pointcloud.unvisibleReasons && pointcloud.unvisibleReasons.length == 1 && pointcloud.unvisibleReasons[0].reason == 'displayMode'   &&  pointcloud.root !== null) {//改 visible -> 
+
+		if ( viewer.getObjVisiByReason(pointcloud, 'datasetSelection') &&  pointcloud.root !== null) {//改 visible -> 
 			priorityQueue.push({pointcloud: i, node: pointcloud.root, weight: Number.MAX_VALUE});
 		}
 
@@ -325,11 +322,8 @@ export function updateVisibility(pointclouds, camera, areaSize){
 			let transformVersion = pointcloudTransformVersion.get(pointcloud);
 			if(node._transformVersion !== transformVersion.number){
 				node.sceneNode.updateMatrix();
-				//node.sceneNode.matrixWorld.multiplyMatrices(pointcloud.matrixWorld, node.sceneNode.matrix);	
 				node.sceneNode.matrixWorld.multiplyMatrices(pointcloud.matrixWorld, node.sceneNode.matrix);	
-				
-                node._transformVersion = transformVersion.number;
-                               
+				node._transformVersion = transformVersion.number;
 			}
 
 			if (pointcloud.showBoundingBox && !node.boundingBoxNode && node.getBoundingBox) {

+ 19 - 24
src/objects/TextSprite.js

@@ -4,31 +4,31 @@
 //  * 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' 
+import * as THREE from "../libs/three.js/build/three.module.js";
+import Sprite from './viewer/Sprite' 
 
 
 //可能还是要用html写,因为要加按钮和图片
 
-export class TextSprite extends THREE.Object3D{ 
-    //注:为了分两层控制scale,不直接extend Sprite
+export class TextSprite extends THREE.Object3D{
+	
 	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.sprite = new Sprite({
+            sizeInfo:options.sizeInfo, 
+            renderOrder:options.renderOrder,
+            useDepth: options.useDepth,
+            map,
+            root: this     
+          
+        })
         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';
@@ -39,12 +39,9 @@ export class TextSprite extends THREE.Object3D{
         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.name = options.name
         
-        
-        this.addEventListener('dispose', this.dispose.bind(this)) 
+		//this.setText(text);
 	}
 
 	setText(text){
@@ -88,21 +85,21 @@ export class TextSprite extends THREE.Object3D{
 	updateTexture(){
 		let canvas = document.createElement('canvas');
 		let context = canvas.getContext('2d');
-		context.font = this.fontWeight + ' ' + this.fontsize + 'px ' + this.fontface; 
+		context.font = 'Bold ' + this.fontsize + 'px ' + this.fontface; 
        
-        //context["font-weight"] = 100; //语法与 CSS font 属性相同。
+        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 margin = new THREE.Vector2(this.fontsize, this.fontsize*0.4);
 		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; 
+		context.font = 'Bold ' + this.fontsize + 'px ' + this.fontface;
 
          
         let diff = 2//针对英文大部分在baseLine之上所以降低一点(metrics.fontBoundingBoxAscent - metrics.fontBoundingBoxDescent) / 2
@@ -168,8 +165,6 @@ export class TextSprite extends THREE.Object3D{
     dispose(){
         this.sprite.material.uniforms.map.value.dispose()
         this.parent && this.parent.remove(this)
-        this.sprite.dispatchEvent({type:'dispose'})
-        this.removeAllListeners()
     }
 
 }

+ 2 - 2
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";
+import math from "./utils/math";
 
 export const CameraMode = {
 	ORTHOGRAPHIC: 0,
@@ -26,7 +26,7 @@ export const ElevationGradientRepeat = {
 	MIRRORED_REPEAT: 2,
 };
 
-export const Buttons = {// MouseEvent.buttons
+export const MOUSE = {// MouseEvent.buttons
     //buttons,设置按下了鼠标哪些键,是一个3个比特位的二进制值,默认为0。1表示按下主键(通常是左键),2表示按下次要键(通常是右键),4表示按下辅助键(通常是中间的键)。
 	NONE:0,//add
     

+ 1 - 1
src/exporter/DXFExporter.js

@@ -7,7 +7,7 @@
  */
 
 import * as THREE from "../../libs/three.js/build/three.module.js";
-import {Measure} from "../objects/tool/Measure.js";
+import {Measure} from "../utils/Measure.js";
 
 export class DXFExporter {
 

+ 1 - 1
src/exporter/GeoJSONExporter.js

@@ -6,7 +6,7 @@
  *
  */
 
-import {Measure} from "../objects/tool/Measure.js";
+import {Measure} from "../utils/Measure.js";
 
 export class GeoJSONExporter{
 

+ 2 - 19
src/loader/BinaryLoader.js

@@ -5,9 +5,6 @@ import {Version} from "../Version.js";
 import {XHRFactory} from "../XHRFactory.js";
 
 
-
-
-//加载 解析点云
 export class BinaryLoader{
 
 	constructor(version, boundingBox, scale){
@@ -31,8 +28,7 @@ export class BinaryLoader{
 		if (this.version.equalOrHigher('1.4')) {
 			url += '.bin';
 		}
-        url += '?m='+node.pcoGeometry.timeStamp //add
-        
+
 		let xhr = XHRFactory.createXMLHttpRequest();
 		xhr.open('GET', url, true);
 		xhr.responseType = 'arraybuffer';
@@ -56,7 +52,7 @@ export class BinaryLoader{
 		}
 	};
 
-	parse(node, buffer){ //解析点云
+	parse(node, buffer){
 		let pointAttributes = node.pcoGeometry.pointAttributes;
 		let numPoints = buffer.byteLength / node.pcoGeometry.pointAttributes.byteSize;
 
@@ -137,20 +133,7 @@ export class BinaryLoader{
 			node.loading = false;
 			node.estimatedSpacing = data.estimatedSpacing;
 			Potree.numNodesLoading--;
-            
-            
-            
-             
-            
-            
-            
-            
-            
-            
-            
 		};
- 
-
 
 		let message = {
 			buffer: buffer,

+ 1 - 1
src/loader/GeoPackageLoader.js

@@ -100,7 +100,7 @@ export class GeoPackageLoader{
 
 				const matLine = new LineMaterial( {
 					color: new THREE.Color().setRGB(...getColor(table)),
-					lineWidth: 2, 
+					linewidth: 2, 
 					resolution:  new THREE.Vector2(1000, 1000),
 					dashed: false
 				} );

+ 2 - 4
src/loader/POCLoader.js

@@ -185,14 +185,12 @@ function lasLazAttributes(fMno){
 
 export class POCLoader {
 
-	static load(url, timeStamp, callback){ //add timeStamp
+	static load(url, callback){
 		try {
 			let pco = new PointCloudOctreeGeometry();
-            pco.timeStamp = timeStamp
-            
 			pco.url = url;
 			let xhr = XHRFactory.createXMLHttpRequest();
-			xhr.open('GET', url+'?m='+timeStamp, true);  
+			xhr.open('GET', url, true);
 
 			xhr.onreadystatechange = function () {
 				if (xhr.readyState === 4 && (xhr.status === 200 || xhr.status === 0)) {

+ 1 - 1
src/loader/ShapefileLoader.js

@@ -14,7 +14,7 @@ export class ShapefileLoader{
 
 		const matLine = new LineMaterial( {
 			color: 0xff0000,
-			lineWidth: 3, // in pixels
+			linewidth: 3, // in pixels
 			resolution:  new THREE.Vector2(1000, 1000),
 			dashed: false
 		} );

+ 0 - 43
src/materials/BasicMaterial.js

@@ -1,43 +0,0 @@
-
-import * as THREE from "../../libs/three.js/build/three.module.js";
-import {Shaders} from "../../build/shaders/shaders.js";
- 
-
-class BasicMaterial  extends THREE.ShaderMaterial{ 
-    constructor(o={}){
-        
-       super( Object.assign({},{ 
-            uniforms:{
-                tDiffuse:    { type: 't',  value: o.map },
-                alpha : {type:'f', value : 1 }
-            },
-            vertexShader: Shaders['basicTextured.vs'],   
-            fragmentShader: Shaders['basicTextured.fs']  
-        },o))
-        
-        
-         
-    }
-    set opacity(o){
-        this.uniforms && (this.uniforms.alpha.value = o)
-         
-    }
-    get opacity(){
-        return this.uniforms.alpha.value  
-    }
-    
-    set map(o){
-        this.uniforms.tDiffuse.value = o
-         
-    }
-    get map(){
-        return this.uniforms.tDiffuse.value  
-    }
-    
-  
-    
-}
-
-
-
-export default BasicMaterial

+ 46 - 72
src/materials/DepthBasicMaterial.js

@@ -1,10 +1,10 @@
 
 import * as THREE from "../../libs/three.js/build/three.module.js";
 import {Shaders} from "../../build/shaders/shaders.js";
-import {Features} from "../Features.js";
-    
+
+
  
-export default class DepthBasicMaterial extends THREE.ShaderMaterial{ 
+export default class DepthBasicMaterial extends THREE.ShaderMaterial{
     constructor(o={}){
         let {width, height} = viewer.renderer.getSize(new THREE.Vector2());
         
@@ -14,22 +14,16 @@ export default class DepthBasicMaterial extends THREE.ShaderMaterial{
 			nearPlane:     { type: 'f', 	value: 0.1 },
 			farPlane:      { type: 'f', 	value: 10000 }, 
 			depthTexture:   { type: 't', 	value: null }, 
-			opacity:        { type: 'f',	value: 1  },
+			opacity:        { type: 'f',	value: o.opacity == void 0 ? 1 : o.opacity },
 			map:             { type: 't', 	value: o.map }, 
-            baseColor:     {type:'v3',      value: o.color ?  new THREE.Color(o.color) :  new THREE.Color("#ffffff")},
-            backColor:     {type:'v3',      value: o.backColor ?  new THREE.Color(o.backColor) :  new THREE.Color("#ddd")},
-            clipDistance :     { type: 'f', 	value:o.clipDistance || 4}, //消失距离
-            occlusionDistance :     { type: 'f', 	value: o.occlusionDistance || 1 }, //变为backColor距离
-            maxClipFactor :  { type: 'f', 	value: o.maxClipFactor || 1 },  //0-1
-      
-
-		}  
+            baseColor:     {type:'v3',      value: o.color ?  new THREE.Color(o.color) :  new THREE.Color("#ffffff"),
+             
+		}};  
         
         let defines = {};
+        if(o.useDepth)defines.useDepth = ''
+        if(o.map)defines.use_map = ''
         
-        let useDepth = o.useDepth && Features.EXT_DEPTH.isSupported()/*  && Potree.settings.matUseDepth */
-        if(useDepth )defines.useDepth = ''
-        if(o.map)defines.use_map = '' 
         super({ 
             uniforms,
             vertexShader: Shaders['depthBasic.vs'],   
@@ -39,80 +33,67 @@ export default class DepthBasicMaterial extends THREE.ShaderMaterial{
             transparent: o.transparent == void 0 ?  true : o.transparent,
             side: o.side || 0 /* THREE.DoubleSide */,
             defines, 
-        })
-        if(o.opacity != void 0){
-            this.opacity = o.opacity
-        }
-       
-        if(useDepth) this.useDepth_ = true
-        
-        
-      
+        } )
         
-        if(this.useDepth){  
+        if(o.useDepth) this.useDepth_ = true
         
-            let setSize = (e)=>{//如果出现横条状的异常,往往是viewportOffset出错 
-                let viewport = e.viewport
-                let viewportOffset = viewport.offset || new THREE.Vector2() 
-                this.uniforms.resolution.value.copy(viewport.resolution2) 
-                this.uniforms.viewportOffset.value.copy(viewportOffset)
-                
-                //console.log('depth '+viewportOffset.toArray())
-            }
-            
-            let viewport = viewer.mainViewport;
-                 
-            setSize( {viewport} )
-            
-            viewer.addEventListener('resize',(e)=>{ 
-                if(!this.useDepth || !e.viewport || e.viewport.camera.isPerspectiveCamera){//地图不需要
-                    setSize(e) 
-                } 
-            })  
-        
-        
-            
-            /* viewer.addEventListener('camera_changed', (e)=>{
-                if(e.viewport.name != 'mapViewport') this.updateDepthParams(e) 
-            }) */ 
          
-            viewer.addEventListener("render.begin", (e)=>{//before render  如果有大于两个viewport的话,不同viewport用不同的depthTex
-                if(e.viewport.camera.isPerspectiveCamera) this.updateDepthParams(e)
-            })
+         
+        let setSize = (e)=>{//如果出现横条状的异常,往往是viewportOffset出错 
+            let viewport = e.viewport
+            let viewportOffset = viewport.offset || new THREE.Vector2() 
+            this.uniforms.resolution.value.copy(viewport.resolution2) 
+            this.uniforms.viewportOffset.value.copy(viewportOffset)
             
-            this.updateDepthParams()
+            //console.log('depth '+viewportOffset.toArray())
         }
+        
+        let viewport = viewer.mainViewport;
          
+        setSize( {viewport} )
+        
+        viewer.addEventListener('resize',(e)=>{
+            if(!e.viewport || e.viewport.name != 'mapViewport'){//地图不需要
+                setSize(e)
+                //console.log(this.name +  viewportOffset.toArray())     
+            } 
+        })  
         
+        
+        viewer.addEventListener('camera_changed', (e)=>{
+            if(e.viewport.name != 'mapViewport') this.updateDepthParams(e) 
+        }) 
+    
+        
+        /* viewer.addEventListener("render.begin", (e)=>{//before render  如果有大于两个viewport的话可能要
+            if(e.viewport.name != 'mapViewport') this.updateDepthParams({camera:e.viewport.camera})
+        }) */
+        
+        this.updateDepthParams()
         //点云变化时要一直触发updateDepthParams??
         //viewer.once("render.pass.end",this.updateDepthParams.bind(this))
     }
     
     updateDepthParams(e={}){//主要用于点云遮住mesh
         if(this.useDepth){ 
-            var viewport = e.viewport || viewer.mainViewport;
-            var camera = viewport.camera;
-            /* if(Potree.settings.displayMode == 'showPanos' && viewer.images360.currentPano.depthTex){
-                this.uniforms.depthTexture.value = viewer.images360.currentPano.depthTex
-            }else{ */
-                this.uniforms.depthTexture.value = viewer.getPRenderer().getRtEDL(viewport).depthTexture   //其实只赋值一次就行
-            //}
+            var camera = e.camera || viewer.scene.getActiveCamera(); 
+            this.uniforms.depthTexture.value = viewer.getPRenderer().rtEDL.depthTexture   //其实只赋值一次就行
             this.uniforms.nearPlane.value = camera.near;
             this.uniforms.farPlane.value = camera.far;
-            
+             
         }            
-    } 
+    }
     set map(map){
         this.uniforms.map.value = map; 
     }
     
     get useDepth(){
         return this.useDepth_
-    } 
+    }
     
-    set useDepth(value){//如果不支持 EXT_DEPTH 的话会失效
+    set useDepth(value){
         if(this.useDepth_ != value){
-            if(value && Features.EXT_DEPTH.isSupported()){
+            if(value){
                 this.defines.useDepth = ''
                 this.updateDepthParams()
             }else{
@@ -124,13 +105,6 @@ export default class DepthBasicMaterial extends THREE.ShaderMaterial{
     } 
     
     
-    get opacity(){
-        return this.uniforms.opacity.value
-    }
-    set opacity(o){
-        this.uniforms && (this.uniforms.opacity.value = o)
-    }
-    
     /* dispose(){ 
         super.dispose()
         viewer.depthBasic

+ 3 - 4
src/materials/EyeDomeLightingMaterial.js

@@ -17,9 +17,8 @@ export class EyeDomeLightingMaterial extends THREE.RawShaderMaterial{
 		super();
 
 		let uniforms = {
-			/* screenWidth:    { type: 'f', 	value: 0 },
-			screenHeight:   { type: 'f', 	value: 0 }, */ 
-            resolution:    { type: 'v2',  value: new THREE.Vector2() },
+			screenWidth:    { type: 'f', 	value: 0 },
+			screenHeight:   { type: 'f', 	value: 0 },
 			edlStrength:    { type: 'f', 	value: 1.0 },
 			uNear:          { type: 'f', 	value: 1.0 },
 			uFar:           { type: 'f', 	value: 1.0 },
@@ -73,7 +72,7 @@ export class EyeDomeLightingMaterial extends THREE.RawShaderMaterial{
 	}
 
 	set neighbourCount(value){
-		if (this._neighbourCount !== value) { //周围八个格子
+		if (this._neighbourCount !== value) {
 			this._neighbourCount = value;
 			this.neighbours = new Float32Array(this._neighbourCount * 2);
 			for (let c = 0; c < this._neighbourCount; c++) {

+ 0 - 395
src/materials/ModelTextureMaterial.js

@@ -1,395 +0,0 @@
-import * as THREE from "../../libs/three.js/build/three.module.js";
-import Common from '../utils/Common.js'
-
-const prefixVertex ="precision highp float;\nprecision highp int;\n\nuniform mat4 modelMatrix;\nuniform mat4 modelViewMatrix;\nuniform mat4 projectionMatrix;\nuniform mat4 viewMatrix;\nuniform mat3 normalMatrix;\nuniform vec3 cameraPosition;\nattribute vec3 position;\nattribute vec3 normal;\nattribute vec2 uv;\n"
-const prefixFragment ="precision highp float;\nprecision highp int;\n\nuniform mat4 viewMatrix;\nuniform vec3 cameraPosition;\n"
- 
-let shader = {
-	 
-		uniforms: { 
-			
-			opacity: {
-				type: "f",
-				value: 1
-			},
-			progress: {
-				type: "f",
-				value: 0
-			},
-			
-			pano0Map: {
-				type: "t",
-				value: null
-			}, 
-            pano1Map: {
-				type: "t",
-				value: null
-			}, 
-            depthMap0: {
-				type: "t",
-				value: null
-			},
-            depthMap1: {
-				type: "t",
-				value: null
-			}, 
-			pano0Position: {
-				type: "v3",
-				value: new THREE.Vector3
-			},
-			pano0Matrix: {
-				type: "m4",
-				value: new THREE.Matrix4
-			},
-			
-			pano1Position: {
-				type: "v3",
-				value: new THREE.Vector3
-			},
-			pano1Matrix: {
-				type: "m4",
-				value: new THREE.Matrix4
-            },
-			/* pano1Matrix2: {
-				type: "m4",
-				value: new THREE.Matrix4
-            },
-            */
-            
-            inverseProjectionMatrix: {
-                value: new THREE.Matrix4
-            },  
-            /* projectionMatrix:{//需要再写一遍吗
-                value: new THREE.Matrix4
-            }, */
-            viewport: {
-                value: new THREE.Vector4
-            },
-            //如     {x: 0, y: 0, z: 428, w: 969}  xy应该是offset, zw是宽高 
-            cameraHeight0: {
-				type: "f",
-				value: 1
-			},
-            cameraHeight1: {
-				type: "f",
-				value: 1
-			},
-            
-        },
-       
-        vertexShader: prefixVertex + `
-
-            uniform vec3 pano0Position;
-            uniform mat4 pano0Matrix;
-            
-            uniform vec3 pano1Position;
-            uniform mat4 pano1Matrix;
-            //uniform mat4 pano1Matrix2;
-
-           
-            varying vec2 vUv; 
-            varying vec3 vWorldPosition0;
-            varying vec3 vWorldPosition1;
-            varying vec3 vWorldPosition12;
-            
-            vec3 transformAxis( vec3 direction ) //navvis->4dkk
-            {
-                float y = direction.y;
-                direction.y = direction.z;
-                direction.z = -y;
-                return  direction;
-            }
-             
-            
-            void main() {
-            
-                vUv = uv;
-                vec4 worldPosition = modelMatrix * vec4(position, 1.0);
-                
-                
-            
-                vec3 positionLocalToPanoCenter0 = worldPosition.xyz - pano0Position;
-                vWorldPosition0 = (vec4(positionLocalToPanoCenter0, 1.0) * pano0Matrix).xyz;
-                vWorldPosition0.x *= -1.0;
-                vWorldPosition0 = transformAxis(vWorldPosition0);
-                
-                vec3 positionLocalToPanoCenter1 = worldPosition.xyz - pano1Position;
-                vWorldPosition1 = (vec4(positionLocalToPanoCenter1, 1.0) * pano1Matrix).xyz;
-                vWorldPosition1.x *= -1.0;
-                vWorldPosition1 = transformAxis(vWorldPosition1);
-                
-                /* 
-                vec3 positionLocalToPanoCenter12 = worldPosition.xyz - pano1Position;
-                vWorldPosition12 = (vec4(positionLocalToPanoCenter12, 1.0) * pano1Matrix2).xyz;
-                vWorldPosition12.x *= -1.0;
-                vWorldPosition12 = transformAxis(vWorldPosition12);
-                 */
-                
-                
-                
-                gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
-            
-            }
-
-        `,
-        fragmentShader: prefixFragment + `
-             
-            #define PI 3.141592653 
-            
-             
-            uniform float modelAlpha;
-            uniform float opacity;
-            uniform float progress;
-            uniform int blackout;
-            uniform vec3 pano0Position;
-            uniform vec3 pano1Position;
-            uniform float maxDistance;
-            uniform float minDistance;
-            uniform float minOpa;
-            
-            uniform float cameraHeight0;
-            uniform float cameraHeight1;
-
-          
-       
-            /* uniform sampler2D pano0Map;
-            uniform sampler2D pano1Map;    */   
-            uniform samplerCube pano0Map;
-            uniform samplerCube pano1Map;
-          
-            
-            varying vec2 vUv; 
-            varying vec3 vWorldPosition0;
-            varying vec3 vWorldPosition1;
-            //varying vec3 vWorldPosition12;
-          
-            /* vec2 getSamplerCoord( vec3 direction ) 
-            {
-                direction = normalize(direction);
-                float tx=atan(direction.x,-direction.y)/(PI*2.0)+0.5;
-                float ty=acos(direction.z)/PI;
-
-                return vec2(tx,ty);
-            } */
-
-            vec2 getSamplerCoord2( vec3 direction ) 
-            { 
-                direction = normalize(direction);
-                float tx=atan(direction.x,direction.z)/(PI*2.0)+0.5;
-                float ty=acos(direction.y)/PI;
-
-                return vec2(tx,ty); 
-            }
-            
-            #extension GL_EXT_frag_depth : enable
-            #if defined(GL_EXT_frag_depth) && defined(hasDepthTex)  
-                uniform sampler2D depthMap0;
-                uniform sampler2D depthMap1;
-                uniform mat4 inverseProjectionMatrix;
-                uniform mat4 projectionMatrix;
-                uniform vec4 viewport; 
-            
-                vec2 getDepth(vec3 dir, sampler2D depthMap, float height, vec4 eyePos){
-                    vec2 depthValue = vec2(0.0, 0.0);
-                    vec2 uv2 = getSamplerCoord2(/* vWorldPosition12 */dir.xyz);  //暂时只用基于目标漫游点的方向
-                    uv2.x -= 0.25;    //全景图和Cube的水平采样起始坐标相差90度,这里矫正 0.25 个采样偏移
-                    vec4 depth = texture2D(depthMap, uv2);
-                    //float distance = depth.r + 256. * (depth.g + 256. * depth.b);
-                    //distance *= 255. * .001;           // distance is now in meters
-                    
-                    //更改
-                    float distance = (depth.g + depth.r / 256.) * 255.;  //为什么要乘以255 
-                    
-                    if(distance == 0.0){//漫游点底部识别不到的区域,给一个地板高度 
-                         if(uv2.y > 0.75)distance = height / dir.y; 
-                         else distance = 100000.0;//给个超级远的值
-                    } 
-                    depthValue.x = distance;
-                    
-                   // return  r[1] + r[0] / 256  
-                    distance += .1;          // add a safety margin
-
-                    vec4 eyePos2 = vec4(normalize(eyePos.xyz) * distance, 1.);
-                    vec4 clipPos2 = projectionMatrix * eyePos2;
-                    vec4 ndcPos2 = clipPos2 * 1. / clipPos2.w;
-
-                    
-                    depthValue.y = 0.5 * ((gl_DepthRange.far - gl_DepthRange.near) * ndcPos2.z
-                            + gl_DepthRange.near + gl_DepthRange.far); 
-                    return depthValue;      
-                }
-                //注:未加载好的话,depth为0,导致第一次漫游过去的时候许多mesh会立刻被遮挡,所以要确保加载完
-            #endif
-            
-            void main()
-            {
-                
-                /* vec2 samplerCoord0 = getSamplerCoord(vWorldPosition0.xyz);
-                vec2 samplerCoord1 = getSamplerCoord(vWorldPosition1.xyz);  
-                vec4 colorFromPano0=texture2D(pano0Map,samplerCoord0);
-                vec4 colorFromPano1=texture2D(pano1Map,samplerCoord1); */
-                
-                vec4 colorFromPano0 = vec4(0.0,0.0,0.0,0.0);
-                if(progress < 1.0){//通常是1
-                    colorFromPano0=textureCube(pano0Map,vWorldPosition0.xyz);
-                }
-                vec4 colorFromPano1=textureCube(pano1Map,vWorldPosition1.xyz);
- 
-                gl_FragColor=mix(colorFromPano0,colorFromPano1,progress);
-              
-              
-                
-              
-                //深度图修改深度
-              
-                #if defined(GL_EXT_frag_depth) && defined(hasDepthTex)  
-                    vec4 ndcPos;
-                    ndcPos.xy = ((2.0 * gl_FragCoord.xy) - (2.0 * viewport.xy)) / (viewport.zw) - 1.;
-                    ndcPos.z = (2.0 * gl_FragCoord.z - gl_DepthRange.near - gl_DepthRange.far) /
-                        (gl_DepthRange.far - gl_DepthRange.near);
-                    ndcPos.w = 1.0;
-
-                    vec4 clipPos = ndcPos / gl_FragCoord.w;
-                    vec4 eyePos = inverseProjectionMatrix * clipPos;
-                    vec2 depth0 = vec2(0.0,0.0); 
-                    if(progress < 1.0){
-                        depth0 = getDepth(vWorldPosition0, depthMap0, cameraHeight0, eyePos);
-                    }
-                    vec2 depth1 = getDepth(vWorldPosition1, depthMap1, cameraHeight1, eyePos);
-                    
-                    /* if(progress < 1.0 && depth1.x == 0.0 && depth0.x > 0.0){
-                        gl_FragDepthEXT = depth0.y; 
-                    }else{ */
-                        gl_FragDepthEXT = mix(depth0.y,depth1.y,progress);
-                    //}
-                    
-                    
-
-                #endif
-
-                
-            }
-        `
-    }
-            
-            
-
-export default class ModelTextureMaterial extends THREE.RawShaderMaterial { 
-	constructor( ){ 
-    
-        let defines = {}
-         
-       
-        
-        super({
-            fragmentShader: shader.fragmentShader,
-			vertexShader: shader.vertexShader,
-			uniforms: THREE.UniformsUtils.clone(shader.uniforms),
-            side:THREE.DoubleSide,
-			name: "ModelTextureMaterial",
-            defines
-        })
-    
-        
-            
-        let setSize = (e)=>{ 
-            let viewport = e.viewport
-            let viewportOffset = viewport.offset || new Vector2()  
-            let resolution = viewport.resolution2 
-            this.uniforms.viewport.value.set(viewportOffset.x, viewportOffset.y, resolution.x, resolution.y) 
-        }
-        let viewport = viewer.mainViewport;
-         
-        setSize({viewport})
-
-
-        viewer.addEventListener('resize',(e)=>{
-            setSize(e)     
-        }) 
-        
-        
-        //var supportExtDepth = !!Features.EXT_DEPTH.isSupported()  
-        {
-         
-            //add
-            
-            viewer.addEventListener('camera_changed', (e)=>{
-                //this.uniforms.projectionMatrix.value.copy(e.camera.projectionMatrix) 
-                this.uniforms.inverseProjectionMatrix.value.copy(e.camera.projectionMatrixInverse)
-            })   
-
-        } 
-
-        
-		//-------------------------------------
-	}
-
-	/**
-	 * 
-	 * @param {Panorama} pano0 
-	 * @param {Panorama} pano1 
-	 * @param {boolean} flag 
-     
-     更新全景图的材质uniforms 
-     
-	 */
-     
-      
-     
-	setProjectedPanos(pano0, pano1, progressValue ){
-        
- 		progressValue!=void 0 && (this.uniforms.progress.value = progressValue);
-		//pano0.ensureSkyboxReadyForRender();
-        
-        
-        if(pano0){
-            this.uniforms.pano0Map.value = pano0.getSkyboxTexture();//pano0.texture
-            this.uniforms.pano0Position.value.copy(pano0.position)
-            this.uniforms.pano0Matrix.value.copy(pano0.panoMatrix/* pano0.mesh.matrixWorld */ );
-            this.uniforms.cameraHeight0.value = pano0.floorPosition.distanceTo(pano0.position)
-            
-            //pano1.ensureSkyboxReadyForRender();
-        }
-        
-		
-		this.uniforms.pano1Map.value = pano1.getSkyboxTexture()//pano1.texture;
-		this.uniforms.pano1Position.value.copy(pano1.position)
-		this.uniforms.pano1Matrix.value.copy(pano1.panoMatrix /* pano1.mesh.matrixWorld */ );
-        this.uniforms.cameraHeight1.value = pano1.floorPosition.distanceTo(pano1.position)
-        this.pano0 = pano0
-        this.pano1 = pano1
-        
-        this.updateDepthTex(pano0)  
-        this.updateDepthTex(pano1)
-        
-        
-        //console.log('setProjectedPanos', pano0&&pano0.id, pano1&&pano1.id)
-        this.needsUpdate = true;
- 	}
-    
-    
-    
-    updateDepthTex(pano){
-        if( !Potree.settings.useDepthTex || !pano || !pano.depthTex || pano!=this.pano0 && pano!=this.pano1)return
-        //console.log('updateDepthTex', pano.id,  this.pano0 && this.pano0.id,  this.pano1 && this.pano1.id)
-        this.uniforms.depthMap0.value = this.pano0 && this.pano0.depthTex 
-        this.uniforms.depthMap1.value = this.pano1 && this.pano1.depthTex 
-        this.updateDepthTexEnable()
-    }
-    
-    updateDepthTexEnable(){
-        let hasDepthTex = this.pano0 && this.pano1 && this.pano0.pointcloud.hasDepthTex && this.pano1.pointcloud.hasDepthTex  //暂时不知道一个有图一个没图怎么写所以
-        
-        Common.addOrRemoveDefine(this, 'hasDepthTex', hasDepthTex?'add':'remove' )
-        
-        
-    }
-    
-    /* EnableDepthTex(){//开启DepthTex
-        if(this.defines['hasDepthTex']){
-            return 
-        }
-        this.defines['hasDepthTex'] = ''
-        this.needsUpdate = true;
-    } */
-}

+ 12 - 33
src/materials/PointCloudMaterial.js

@@ -5,7 +5,7 @@ import {Gradients} from "./Gradients.js";
 import {Shaders} from "../../build/shaders/shaders.js";
 import {ClassificationScheme} from "./ClassificationScheme.js";
 import {PointSizeType, PointShape, TreeType, ElevationGradientRepeat} from "../defines.js";
-import {Features} from "../Features.js";
+
 //
 // how to calculate the radius of a projected sphere in screen space
 // http://stackoverflow.com/questions/21648630/radius-of-projected-sphere-in-screen-space
@@ -90,9 +90,8 @@ export class PointCloudMaterial extends THREE.RawShaderMaterial {
 			blendHardness:		{ type: "f", value: 2.0 },
 			blendDepthSupplement:	{ type: "f", value: 0.0 },
 			fov:				{ type: "f", value: 1.0 },
-			/* screenWidth:		{ type: "f", value: 1.0 },
-			screenHeight:		{ type: "f", value: 1.0 }, */
-            resolution:    { type: 'v2',  value: new THREE.Vector2() },
+			screenWidth:		{ type: "f", value: 1.0 },
+			screenHeight:		{ type: "f", value: 1.0 },
 			near:				{ type: "f", value: 0.1 },
 			far:				{ type: "f", value: 1.0 },
 			uColor:				{ type: "c", value: new THREE.Color( 0xffffff ) },
@@ -281,20 +280,14 @@ export class PointCloudMaterial extends THREE.RawShaderMaterial {
 		} else if (this.pointSizeType === PointSizeType.ADAPTIVE) {
 			defines.push('#define adaptive_point_size');
 		}
-        
-        if(!Features.EXT_DEPTH.isSupported() && this.shape === PointShape.PARABOLOID){
-            this.shape = PointShape.SQUARE ;//强行替换
-        }
-        
-        
+
 		if (this.shape === PointShape.SQUARE) {
 			defines.push('#define square_point_shape');
 		} else if (this.shape === PointShape.CIRCLE) {
 			defines.push('#define circle_point_shape');
-		}  else if (this.shape === PointShape.PARABOLOID) { 
+		} else if (this.shape === PointShape.PARABOLOID) {
 			defines.push('#define paraboloid_point_shape');
-		}  
-        //console.log('this.shape PARABOLOID', this.shape, this.shape === PointShape.PARABOLOID)
+		}
 
 		if (this._useEDL || this.fakeEDL) {
 			defines.push('#define use_edl');
@@ -540,7 +533,7 @@ export class PointCloudMaterial extends THREE.RawShaderMaterial {
 		}
 	}
 
-	/* get screenWidth () {
+	get screenWidth () {
 		return this.uniforms.screenWidth.value;
 	}
 
@@ -549,7 +542,7 @@ export class PointCloudMaterial extends THREE.RawShaderMaterial {
 			this.uniforms.screenWidth.value = value;
 			// this.updateShaderSource();
 		}
-	} 
+	}
 
 	get screenHeight () {
 		return this.uniforms.screenHeight.value;
@@ -560,19 +553,8 @@ export class PointCloudMaterial extends THREE.RawShaderMaterial {
 			this.uniforms.screenHeight.value = value;
 			// this.updateShaderSource();
 		}
-	}*/
-    
-    //add--------------
-    get resolution(){
-        return this.uniforms.resolution.value
-    }
-    set resolution(value){
-        this.uniforms.resolution.value.copy(value);
-    }
-    //--------------
-    
-    
-    
+	}
+
 	get near () {
 		return this.uniforms.near.value;
 	}
@@ -640,12 +622,9 @@ export class PointCloudMaterial extends THREE.RawShaderMaterial {
 	}
 
 	set pointSizeType (value) {
-        
-        if(typeof value == 'string' )value = PointSizeType[value]
-        
 		if (this._pointSizeType !== value) {
 			this._pointSizeType = value;
-			this.updateShaderSource();              //这句表明这个属性频繁更改会卡顿
+			this.updateShaderSource();
 			this.dispatchEvent({
 				type: 'point_size_type_changed',
 				target: this
@@ -689,7 +668,7 @@ export class PointCloudMaterial extends THREE.RawShaderMaterial {
         if(typeof value == 'string') {
             var colorArr = Potree.config.colors[value]  
             if(!colorArr){ 
-                //console.warn('没找到该颜色值'+ value)
+                console.warn('没找到该颜色值'+ value)
             }else{
                 color = new THREE.Color().fromArray(colorArr).multiplyScalar(1/255)
             }                

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

@@ -2,10 +2,6 @@ varying vec2 vUv;
 uniform float opacity;
 
 uniform vec3 baseColor;
-uniform vec3 backColor;
-uniform float occlusionDistance;
-uniform float clipDistance;
-uniform float maxClipFactor;
 
 
 #if defined use_map
@@ -49,23 +45,24 @@ void main() {
         float fragDepth = convertToLinear(gl_FragCoord.z);
 
         // The coordinates of the current fragment in the depth texture
-        vec2 depthTxtCoords = vec2(gl_FragCoord.x-viewportOffset.x,  gl_FragCoord.y - viewportOffset.y) / resolution;
+        vec2 depthTxtCoords = vec2(gl_FragCoord.x-viewportOffset.x,  gl_FragCoord.y) / resolution;
      
         // The linear depth value of the pixel occupied by this fragment in the depth buffer
         float textureDepth = convertToLinear(texture2D(depthTexture, depthTxtCoords).r);
 
         // The difference between the two depths
-        float delta =  fragDepth - textureDepth;
+        float delta = textureDepth - fragDepth;
 
-        if (delta > 0.0)//差距
+        if (delta < 0.0)//差距
         {
             // occlusionDistance and clipDistance define the width of the respective zones and
             // mixFactor and clipFactor express the interpolation between the two colors depending on the position
             // of the current fragment withing those zones.
             
-            
+            float occlusionDistance = - 1.0; //1米
+            float clipDistance = - 4.0;
             mixFactor = clamp(delta / occlusionDistance, 0.0, 1.0);
-            clipFactor = clamp(delta / clipDistance, 0.0, maxClipFactor);
+            clipFactor = clamp(delta / clipDistance, 0.0, 1.0);
         }
         
         // If the fragment is totally transparent, don't bother drawing it
@@ -78,8 +75,8 @@ void main() {
                 color = texture2D(map, vUv) * color; 
             #endif
            
+            vec3 backColor = vec3(0.8,0.8,0.8); 
             
-             
             color = vec4(mix(color.rgb, backColor, mixFactor), color.a * (1.0 - clipFactor));
         }
          

+ 12 - 23
src/materials/shaders/edl.fs

@@ -9,11 +9,8 @@
 precision mediump float;
 precision mediump int;
 
-//uniform float screenWidth;
-//uniform float screenHeight;
-uniform vec2 resolution;
-
-
+uniform float screenWidth;
+uniform float screenHeight;
 uniform vec2 neighbours[NEIGHBOUR_COUNT];
 uniform float edlStrength;
 uniform float radius;
@@ -32,22 +29,22 @@ varying vec2 vUv;
 uniform int useEDL;
 
 float response(float depth){
-	vec2 uvRadius = radius / resolution;             //vec2(screenWidth, screenHeight);
+	vec2 uvRadius = radius / vec2(screenWidth, screenHeight);
 	
 	float sum = 0.0;
 	
 	for(int i = 0; i < NEIGHBOUR_COUNT; i++){
 		vec2 uvNeighbor = vUv + uvRadius * neighbours[i];
-		//获取周围八个格子的值
+		
 		float neighbourDepth = texture2D(uEDLColor, uvNeighbor).a;
 		neighbourDepth = (neighbourDepth == 1.0) ? 0.0 : neighbourDepth;
 
 		if(neighbourDepth != 0.0){
-			//if(depth == 0.0){
-			//	sum += 100.0;
-			//}else{
-				sum += max(0.0, depth - neighbourDepth);  //获取差值
-			//}
+			if(depth == 0.0){
+				sum += 100.0;
+			}else{
+				sum += max(0.0, depth - neighbourDepth);
+			}
 		}
 	}
 	
@@ -60,25 +57,17 @@ void main(){
 	float depth = cEDL.a;
 	depth = (depth == 1.0) ? 0.0 : depth;
     
-    if(depth == 0.0){ //去掉这句就能在无点云像素的地方渲染outline,但会遮住其他mesh
+    if(depth == 0.0){
 		discard;
 	}
     
     
     if(useEDL == 1){
         float res = response(depth);
-        
-        //if(depth == 0.0 && res == 0.0){   //test
-        //    discard;
-        //}
-         
-        float shade = exp(-res * 300.0 * edlStrength); //自然常数e为底的指数函数
+        float shade = exp(-res * 300.0 * edlStrength);
 
         gl_FragColor = vec4(cEDL.rgb * shade, opacity); 
-        
-        //const vec3 outlineColor = vec3(1.0,0.0,0.0);//test -outline
-        //gl_FragColor = vec4(mix(cEDL.rgb, outlineColor, -res), opacity );
-    }else{//加  不改颜色的情况 
+    }else{//加  不改颜色的情况
         gl_FragColor = vec4(cEDL.rgb, opacity);
     } 
     

+ 1 - 1
src/materials/shaders/pointcloud.fs

@@ -130,7 +130,7 @@ void main() {
 	
  
     #if defined color_type_indices    //pick point recognize
-		gl_FragColor = vec4(color, uPCIndex / 255.0); //uPCIndex : node Index
+		gl_FragColor = vec4(color, uPCIndex / 255.0);
 	#else
 		gl_FragColor = vec4(color, vOpacity);
 	#endif

+ 16 - 43
src/materials/shaders/pointcloud.vs

@@ -46,7 +46,7 @@ attribute float classification;
 attribute float returnNumber;
 attribute float numberOfReturns;
 attribute float pointSourceID;
-attribute vec4 indices;    //每个点的index
+attribute vec4 indices;
 attribute float spacing;
 attribute float gpsTime;
 attribute vec3 normal;
@@ -58,11 +58,8 @@ uniform mat4 projectionMatrix;
 uniform mat4 viewMatrix;
 uniform mat4 uViewInv;
 
-//uniform float uScreenWidth;
-//uniform float uScreenHeight;
-uniform vec2 resolution;
-
-
+uniform float uScreenWidth;
+uniform float uScreenHeight;
 uniform float fov;
 uniform float near;
 uniform float far;
@@ -717,10 +714,7 @@ float getPointSize(){
 	float pointSize = 1.0;
 	
 	float slope = tan(fov / 2.0);
-	float projFactor = -0.5 * resolution.y / (slope * vViewPosition.z);
-    
-    
-    
+	float projFactor = -0.5 * uScreenHeight / (slope * vViewPosition.z);
     /*
 	float scale = length(
 		modelViewMatrix * vec4(0, 0, 0, 1) - 
@@ -739,7 +733,7 @@ float getPointSize(){
 		pointSize = size;
 	#elif defined attenuated_point_size
 		if(uUseOrthographicCamera){
-			pointSize = size * 10.0;  //加个乘数
+			pointSize = size;
 		}else{  //近大远小,模拟真实mesh,边缘放大
 			//pointSize = size * spacing * projFactor;  //spacing是attribute  为空  如果有这个值就能更自适应填补
             //pointSize = size * uOctreeSpacing * projFactor / 18.0; //直接用cloud的spacing里,不过因为都一样所以可能没有什么意义
@@ -749,7 +743,7 @@ float getPointSize(){
 	#elif defined adaptive_point_size
 		if(uUseOrthographicCamera) {
 			float worldSpaceSize = 1.0 * size * r / getPointSizeAttenuation();
-			pointSize = (worldSpaceSize / uOrthoWidth) * resolution.x;    //uScreenWidth;
+			pointSize = (worldSpaceSize / uOrthoWidth) * uScreenWidth;
 		} else {
 			float worldSpaceSize = 1.0 * size * r / getPointSizeAttenuation();
 			pointSize = worldSpaceSize * projFactor;
@@ -938,29 +932,21 @@ vec3 transformAxis( vec3 direction ) //navvis->4dkk
 }
 
 void main() {
-    //bool filtered_by_normal = false; 
-    float normalZ = 0.0;
-
-
-
+    
     #ifdef use_filter_by_normal
-        /*if(abs(getNormal().z) > 0.4) { //ufilterByNormalThreshold 暂定 3
+        if(abs(getNormal().z) > 0.3) { //ufilterByNormalThreshold 暂定0.3
 			// Move point outside clip space space to discard it.
-			//gl_Position = vec4(0.0, 0.0, 2.0, 1.0);   //gl_Position的可视区域是 x,y,z都是[-1,1]  
-            //return;
-            //filtered_by_normal = true; //标记一下。不直接不绘制,因为有的法线都是垂直向上
-             
-		}*/
-        
-        normalZ = abs(getNormal().z);
+			gl_Position = vec4(0.0, 0.0, 2.0, 1.0);
+            return;
+		}
     #endif
      
     vec4 mvPosition = modelViewMatrix * vec4(position, 1.0 );
     vViewPosition = mvPosition.xyz;
     gl_Position = projectionMatrix * mvPosition;
     vLogDepth = log2(-mvPosition.z);
-    
-    
+
+
      
     // COLOR
     //加-------------------
@@ -1013,25 +999,12 @@ void main() {
    
    
     //-------------------        
- 
+
+    //数据集校准时,相机拉远后随着点云密集需降低透明度 
     #ifdef attenuated_opacity  
-        //zoom不会改变z 所以这并不是用在分屏时候的
-        //vOpacity = uOpacity * exp(-length(-mvPosition.xyz) / 1000.0);  // e为底的指数函数  opacityAttenuation = 1000
-        vOpacity = uOpacity  * exp(gl_Position.z/50.0); 
-        vOpacity = clamp(vOpacity, 0.001, 1.0);          
-        /*if(filtered_by_normal){//垂直朝相机时降低透明度 
-            vOpacity *= 0.2; 
-            vOpacity = clamp(vOpacity, 0.0001, 0.1);    
-        } */  
+        vOpacity = uOpacity * exp(-length(-mvPosition.xyz) / 1000.0);  //opacityAttenuation = 1000
     #else
         vOpacity = uOpacity;
-        /*if(filtered_by_normal){//垂直朝相机时降低透明度 
-        /*if(filtered_by_normal){//垂直朝相机时降低透明度 
-            vOpacity *= 0.3; 
-            vOpacity = clamp(vOpacity, 0.0001, 0.1);    
-        }*/ 
-        
-        vOpacity *= max(0.1,  (1.0 - normalZ));
     #endif
 	 
 

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 399 - 521
src/modules/CameraAnimation/CameraAnimation.js


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 458 - 1798
src/modules/Images360/Images360.js


+ 207 - 0
src/modules/Images360/ModelTextureMaterial.js

@@ -0,0 +1,207 @@
+import * as THREE from "../../../libs/three.js/build/three.module.js";
+const prefixVertex ="precision highp float;\nprecision highp int;\n\nuniform mat4 modelMatrix;\nuniform mat4 modelViewMatrix;\nuniform mat4 projectionMatrix;\nuniform mat4 viewMatrix;\nuniform mat3 normalMatrix;\nuniform vec3 cameraPosition;\nattribute vec3 position;\nattribute vec3 normal;\nattribute vec2 uv;\n"
+const prefixFragment ="precision highp float;\nprecision highp int;\n\nuniform mat4 viewMatrix;\nuniform vec3 cameraPosition;\n"
+ 
+let shader = {
+	 
+		uniforms: { 
+			
+			opacity: {
+				type: "f",
+				value: 1
+			},
+			progress: {
+				type: "f",
+				value: 0
+			},
+			
+			pano0Map: {
+				type: "t",
+				value: null
+			},
+			pano0Position: {
+				type: "v3",
+				value: new THREE.Vector3
+			},
+			pano0Matrix: {
+				type: "m4",
+				value: new THREE.Matrix4
+			},
+			pano1Map: {
+				type: "t",
+				value: null
+			},
+			pano1Position: {
+				type: "v3",
+				value: new THREE.Vector3
+			},
+			pano1Matrix: {
+				type: "m4",
+				value: new THREE.Matrix4
+            } 
+            
+        },
+       
+        vertexShader: prefixVertex + `
+
+            uniform vec3 pano0Position;
+            uniform mat4 pano0Matrix;
+            
+            uniform vec3 pano1Position;
+            uniform mat4 pano1Matrix;
+
+           
+            varying vec2 vUv;
+            varying vec3 vWorldPosition0;
+            varying vec3 vWorldPosition1;
+            
+            vec3 transformAxis( vec3 direction ) //navvis->4dkk
+            {
+                float y = direction.y;
+                direction.y = direction.z;
+                direction.z = -y;
+                return  direction;
+            }  
+            
+            
+            
+            void main() {
+            
+                vUv = uv;
+                vec4 worldPosition = modelMatrix * vec4(position, 1.0);
+                
+                
+            
+                vec3 positionLocalToPanoCenter0 = worldPosition.xyz - pano0Position;
+                vWorldPosition0 = (vec4(positionLocalToPanoCenter0, 1.0) * pano0Matrix).xyz;
+                vWorldPosition0.x *= -1.0;
+                vWorldPosition0 = transformAxis(vWorldPosition0);
+                
+                vec3 positionLocalToPanoCenter1 = worldPosition.xyz - pano1Position;
+                vWorldPosition1 = (vec4(positionLocalToPanoCenter1, 1.0) * pano1Matrix).xyz;
+                vWorldPosition1.x *= -1.0;
+                vWorldPosition1 = transformAxis(vWorldPosition1);
+                
+                gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
+            
+            }
+
+        `,
+        fragmentShader: prefixFragment + `
+
+            #define PI 3.141592653 
+            
+             
+            uniform float modelAlpha;
+            uniform float opacity;
+            uniform float progress;
+            uniform int blackout;
+            uniform vec3 pano0Position;
+            uniform vec3 pano1Position;
+            uniform float maxDistance;
+            uniform float minDistance;
+            uniform float minOpa;
+            
+          
+       
+            /* uniform sampler2D pano0Map;
+            uniform sampler2D pano1Map;    */   
+            uniform samplerCube pano0Map;
+            uniform samplerCube pano1Map;
+          
+            
+            varying vec2 vUv;
+            varying vec3 vWorldPosition0;
+            varying vec3 vWorldPosition1;
+
+          
+            vec2 getSamplerCoord( vec3 direction ) 
+            {
+                direction = normalize(direction);
+                float tx=atan(direction.x,-direction.y)/(PI*2.0)+0.5;
+                float ty=acos(direction.z)/PI;
+
+                return vec2(tx,ty);
+            }  
+            void main()
+            {
+                
+                /* vec2 samplerCoord0 = getSamplerCoord(vWorldPosition0.xyz);
+                vec2 samplerCoord1 = getSamplerCoord(vWorldPosition1.xyz);  
+                vec4 colorFromPano0=texture2D(pano0Map,samplerCoord0);
+                vec4 colorFromPano1=texture2D(pano1Map,samplerCoord1); */
+                
+                vec4 colorFromPano0=textureCube(pano0Map,vWorldPosition0.xyz);
+                vec4 colorFromPano1=textureCube(pano1Map,vWorldPosition1.xyz);
+
+                
+
+
+
+
+                gl_FragColor=mix(colorFromPano0,colorFromPano1,progress);
+              
+                
+            }
+        `
+    }
+            
+            
+
+export default class ModelTextureMaterial extends THREE.RawShaderMaterial { 
+	constructor( ){ 
+        
+        super({
+            fragmentShader: shader.fragmentShader,
+			vertexShader: shader.vertexShader,
+			uniforms: THREE.UniformsUtils.clone(shader.uniforms),
+            side:THREE.DoubleSide,
+			name: "ModelTextureMaterial"
+            
+        })
+        
+        
+        /* var defines = parameters.defines || {}
+        defines.Not_Cube = "";
+        parameters.defines = defines; 
+		
+ 
+		super(common.extendObject({
+			fragmentShader: shaders[matName].fragmentShader,
+			vertexShader: shaders[matName].vertexShader,
+			uniforms: THREE.UniformsUtils.clone(shaders[matName].uniforms),
+			name: "ModelTextureMaterial"
+		}, parameters));*/
+        
+        
+		//-------------------------------------
+	}
+
+	/**
+	 * 
+	 * @param {Panorama} pano0 
+	 * @param {Panorama} pano1 
+	 * @param {boolean} flag 
+     
+     更新全景图的材质uniforms 
+     
+	 */
+	setProjectedPanos(pano0, pano1, progressValue ){
+        
+ 		progressValue!=void 0 && (this.uniforms.progress.value = progressValue);
+		//pano0.ensureSkyboxReadyForRender();
+		this.uniforms.pano0Map.value = pano0.getSkyboxTexture();//pano0.texture
+		this.uniforms.pano0Position.value.copy(pano0.position)
+		this.uniforms.pano0Matrix.value.copy(pano0.panoMatrix/* pano0.mesh.matrixWorld */ );
+		//pano1.ensureSkyboxReadyForRender();
+ 
+        
+		
+		this.uniforms.pano1Map.value = pano1.getSkyboxTexture()//pano1.texture;
+		this.uniforms.pano1Position.value.copy(pano1.position)
+		this.uniforms.pano1Matrix.value.copy(pano1.panoMatrix /* pano1.mesh.matrixWorld */ );
+        
+        
+        this.needsUpdate = true;
+ 	}
+}

+ 140 - 381
src/modules/Images360/Panorama.js

@@ -1,41 +1,27 @@
 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 TileUtils from './tile/TileUtils'
+import { PanoRendererEvents, PanoramaEvents, PanoSizeClass} from '../../defines'
+import math from '../../utils/math'
+import { EventDispatcher } from "../../EventDispatcher.js";
+import {TextSprite} from '../../TextSprite'
 
 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 }, 
+    sizeInfo: {minSize : 120 ,  maxSize : 200,   nearBound : 0.8, farBound : 10},
+    backgroundColor:{r: 255, g: 255, b: 255, a: 0.2 },
     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  
-        //有可能被点云遮住吗。 
-     
+    if(!standardMarkerMat) {
+        let map = texLoader.load( Potree.resourcePath+'/textures/marker.png' )
+        map.anisotropy = 4 // 各向异性过滤 .防止倾斜模糊
+        standardMarkerMat = new THREE.MeshBasicMaterial({opacity:0.7, side: THREE.DoubleSide , map ,transparent:true, depthTest:false})//总是被点云遮住,所以depthTest:false
     }
-    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的材质过渡时会先隐藏后出现
-    })    
+    return standardMarkerMat.clone()
 }
 //显示全景图时marker没有被遮挡,如果需要,要换成depthBasicMaterial  或者直接把skybox的深度修改(拿到深度贴图后更如此)
 let planeGeo = new THREE.PlaneBufferGeometry(0.2,0.2);
@@ -64,130 +50,78 @@ var a = new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(0,0,1), THREE.
  */
 
 //暂时直接用4dkkconsole输出的数据 
-class Panorama extends THREE.EventDispatcher{
+class Panorama extends EventDispatcher{
 
-	constructor(o,  images360){//file, time, longitude, latitude, altitude, course, pitch, roll
+	constructor(o, transform, images360){//file, time, longitude, latitude, altitude, course, pitch, roll
         super()
-        this.id = o.id; //唯一标识
+        this.id = o.id;
         this.images360 = images360
+        this.transform =  transform
         this.visible = true  //for viewer updateVisible
-        this.enabled = true//是否可以走
+         
+        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.pointcloud.addEventListener('isVisible',(e)=>{ 
+            /* if(!e.visible){//数据集隐藏时漫游点也隐藏
+                e.reason == 'datasetSelection' && viewer.updateVisible(this, 'pointcloudVisi', false) 
+            }else{
+                console.log('pointcloudVisi 1')
+                viewer.updateVisible(this, 'pointcloudVisi', true) 
+            } */
+            e.reason == 'datasetSelection' && viewer.updateVisible(this, 'pointcloudVisi', e.visible) 
+            
+        })
         this.addEventListener('isVisible',(e)=>{//是否显示该点的mesh(不显示也能走)
-            //console.log('pano isVisible', this.id, e.visible) 
-            viewer.updateVisible(this.marker, 'panoVisi', e.visible)
+            this.marker.visible = e.visible
             Potree.settings.showPanoMesh && (this.mesh.visible = e.visible)
             if(e.reason == 'screenshot' || e.visible){
                 this.label && (this.label.visible = e.visible)//截图时隐藏下
             }
-            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度 
-            
+        
+        //全景图和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{ */
+        /* 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) //转化坐标
                 
-                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`
+        }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.rotation = new THREE.Euler().setFromQuaternion(this.quaternion) 
+            this.quaternion = new THREE.Quaternion().multiplyQuaternions(this.quaternion,  rot90);//全景图和Cube的水平采样起始坐标相差90度,cubeTex转90度
+            
+            this.rotation4dkk = new THREE.Euler().setFromQuaternion(this.quaternion4dkk)
+            this.rotation = new THREE.Euler().setFromQuaternion(this.quaternion) 
+         //}
+         
+         
+            //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.build()
         this.transformByPointcloud() //初始化位移
+         
+        
         
         {//tile
             this.minimumTiledPanoLoaded = !1;
@@ -201,22 +135,22 @@ class Panorama extends THREE.EventDispatcher{
             
             
            
-            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));
+            images360.panoRenderer.on(PanoRendererEvents.TileRenderSuccess, this.onTileRendered.bind(this));
+            images360.panoRenderer.on(PanoRendererEvents.PanoRenderComplete, this.onPanoRendered.bind(this));
+            images360.panoRenderer.on(PanoRendererEvents.TileRenderFailure, this.onTileRenderFail.bind(this));
+            images360.panoRenderer.on(PanoRendererEvents.UploadAttemptedForAllTiles, this.onUploadAttemptedForAllTiles.bind(this));
             
         }
         
         
         
-        this.addEventListener('hoverOn', (e)=>{//from Map
+        this.on('hoverOn', (e)=>{//from Map
             if(!e.byMainView){ 
                 this.hoverOn(e) 
             } 
         })
         
-        this.addEventListener('hoverOff', (e)=>{
+        this.on('hoverOff', (e)=>{
             if(!e.byMainView){
                 this.hoverOff(e) 
             } 
@@ -225,38 +159,15 @@ class Panorama extends THREE.EventDispatcher{
     
 
 
-    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); 
+        let mesh = new THREE.Mesh(sg, sm); 
         mesh.scale.set(1, 1, 1);
         mesh.material.transparent = true;
         mesh.material.opacity = 0.75;
@@ -270,12 +181,7 @@ class Panorama extends THREE.EventDispatcher{
         })
         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) 
@@ -285,98 +191,49 @@ class Panorama extends THREE.EventDispatcher{
             //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
         } 
-        
-        
+        this.mesh = mesh;
+        if(!Potree.settings.showPanoMesh) mesh.visible = false
          
         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(mesh)
         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 position = this.originPosition.clone().applyMatrix4(this.pointcloud.transformMatrix);
         let floorPosition = this.originFloorPosition.clone().applyMatrix4(this.pointcloud.transformMatrix);
         this.setPosition(position, floorPosition) 
         this.panoMatrix = new THREE.Matrix4().multiplyMatrices(this.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')
+    
+        //quaternion也变下  
     }
     
     setPosition(position, floorPosition){
         this.position = position
         this.floorPosition = floorPosition
-        //this.mesh.position.copy(this.position)
+        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.marker.position.z+=0.1//会被点云遮住
+        if(this.label){
+            this.label.position.copy(this.floorPosition), this.label.position.z+=0.2
             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()
-        }
           
     }
     
@@ -390,8 +247,7 @@ class Panorama extends THREE.EventDispatcher{
     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})
+		if(!e.byMap) this.emit('hoverOn', {byMainView:true})
     }
 
  
@@ -400,8 +256,7 @@ class Panorama extends THREE.EventDispatcher{
     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})
+        if(!e.byMap) this.emit('hoverOff', {byMainView:true})
     }
     
     
@@ -409,14 +264,14 @@ class Panorama extends THREE.EventDispatcher{
     setZoomed(zoomed){
         this.zoomed = zoomed;
         Potree.settings.displayMode == 'showPanos' && this.updateSkyboxForZoomLevel(); //放大后换成zoomTarget贴图
-        viewer.dispatchEvent({type:'panoSetZoom', zoomed})
+        viewer.emit('panoSetZoom', this, zoomed)
         
     }
     
     
     enter(){ 
         this.setZoomed(!1),
-        viewer.dispatchEvent({type:PanoramaEvents.Enter,  oldPano:old, newPano:this  }  )
+        viewer.emit(PanoramaEvents.Enter,  {oldPano:old, newPano:this  }  )
         old = this 
         //console.log("enter pano "+ this.id)
     } 
@@ -441,7 +296,7 @@ class Panorama extends THREE.EventDispatcher{
         
         //console.log("exit pano "+ this.id)
         
-        viewer.dispatchEvent({type:PanoramaEvents.Exit, pano:this}); 
+        viewer.emit(PanoramaEvents.Exit, this); 
     }
     
     
@@ -476,11 +331,15 @@ class Panorama extends THREE.EventDispatcher{
     
    
     
-    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, 希望这代表全部加载完
-     
+    isLoaded(e){
+        //if (this.tiled) {
+            if (e && "string" == typeof e)
+                console.error("Wrong panoSize given to Panorama.isLoaded(); a tiled pano uses PanoSizeClass");
+            return !!this.minimumTiledPanoLoaded && (!e || this.highestPartialTileRenderOpCompleted >= e)
+        //}
+        /* if (e && "number" == typeof e)
+            throw new BasicException("Wrong panoSize given to Panorama.isLoaded(); a non-tiled pano uses high/low.");
+        return !!this.solidSkybox.high || e in this.solidSkybox */
     }
 
     getWaitDeferred(size){//获取不同size的tile贴图的promiss 
@@ -511,33 +370,30 @@ class Panorama extends THREE.EventDispatcher{
         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
-        });
+    onTileRendered(e, t, i, n){
+        e === this.id && this.dispatchEvent({type:PanoramaEvents.TileLoaded,  size:t, index:i, count:n});
     }
 
-    onPanoRendered(ev) { 
-        if(ev.id === this.id)  
+    onPanoRendered(e, t, i, n) {
+        if(e === 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);
+            t > this.highestPartialTileRenderOpCompleted && (this.highestPartialTileRenderOpCompleted = t);//应该是更新最高获取到的Partial size
+            !n && t > this.highestFullTileRenderOpCompleted && (this.highestFullTileRenderOpCompleted = t); //应该是更新最高获取到的Full size
+            //this.emit("load", t);
             viewer.ifAllLoaded( this);
-            this.dispatchEvent({type:PanoramaEvents.LoadComplete, size:ev.panoSize, count:ev.totalTiles});
+            this.dispatchEvent({type:PanoramaEvents.LoadComplete, size:t, count:i});
         }
     }
  
-    onTileRenderFail(ev) { 
-        ev.id === this.id && this.dispatchEvent({type:PanoramaEvents.LoadFailed   });
+    onTileRenderFail(e, t, i) {
+        e === this.id && this.dispatchEvent({type:PanoramaEvents.LoadFailed, t});
     }
-    onUploadAttemptedForAllTiles(ev) { 
-        if (ev.id === this.id) {        
+    onUploadAttemptedForAllTiles(e, t, i) {
+        if (e === this.id) {
             var n = this.images360.qualityManager.getPanoSize(PanoSizeClass.BASE);
-            if(ev.panoSize === n && this.shouldRedrawOnBaseLoaded) //shouldRedrawOnBaseLoaded一直是false。在4dkk里只有初始点在quickstart后变为true。
+            if(t === n && this.shouldRedrawOnBaseLoaded)
             {
                 this.shouldRedrawOnBaseLoaded = !1;
                 this.panoRenderer.resetRenderStatus(this.id, !0, !1);
@@ -550,119 +406,58 @@ class Panorama extends THREE.EventDispatcher{
     
     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.label = new TextSprite($.extend(
+           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){ 
+        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对应一组这些
-         
+    var downloads = []  , t = [];
+    
     return function(size, dirs, fov, o, a, download) {
-        var dir = dirs.datasetsLocal.find(e=>e.datasetId == this.pointcloud.dataset_id).direction;
+        var dir = dirs.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; 
+          , 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
-                    }
-                     
+                    var d = TileUtils.matchingTilesInDirection(this, size, dir, h, u);
+                    downloads[this.id + ":" + size] = {
+                        tileCount: 0,
+                        targetTileCount: d
+                    } 
                     //console.log("Loading partial pano: " + this.id + " with " + d + " tiles")
                 }
-                if(!eventAdded[this.id]) {
-                    eventAdded[this.id] = !0 
+                if(!t[this.id]) {
+                    t[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
@@ -675,62 +470,26 @@ Panorama.prototype.loadTiledPano = function() {
                     }.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;
+                        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.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()
     }

+ 44 - 85
src/modules/Images360/tile/PanoRenderer.js

@@ -1,14 +1,15 @@
  
-import {PanoSizeClass, PanoRendererEvents , Vectors,SceneRendererEvents,TileDownloaderEvents, GLCubeFaces} from '../../../defines.js'
+import {PanoSizeClass, PanoRendererEvents , Vectors,SceneRendererEvents,TileDownloaderEvents, GLCubeFaces} from '../../../defines'
  
 import {Shaders} from "../../../../build/shaders/shaders.js";
-import TileTree from './TileTree.js'
-import TilePrioritizer from './TilePrioritizer.js'
+import TileTree from './TileTree'
+import TilePrioritizer from './TilePrioritizer'
 import TileUtils from './TileUtils' 
-import {settings,config} from '../../../settings.js'
+import {settings,config} from '../../../settings'
 /* import config from '../../config' */
-import * as THREE from "../../../../libs/three.js/build/three.module.js"; 
-import math from '../../../utils/math.js' 
+import * as THREE from "../../../../libs/three.js/build/three.module.js";
+import { EventDispatcher } from "../../../EventDispatcher.js";
+import math from '../../../utils/math' 
 
 function createDescriptor() {
     var e = {
@@ -47,7 +48,7 @@ var b = !1,
     }/* ,
     M = []; */
 
-class PanoRenderer extends THREE.EventDispatcher{
+class PanoRenderer extends EventDispatcher{
     constructor(viewer, tileDownloader, qualityManager) {
         super()
 		this.tileDirectory = {};
@@ -310,7 +311,7 @@ class PanoRenderer extends THREE.EventDispatcher{
             if(i){
                 this.uploadTile(e, !1)//提交
             }else{
-                if(this.shoulPushToFrontOfQueue(e)){//如果是512的优先
+                if(this.shoulPushToFrontOfQueue(e)){
                     this.forceQueue.push(e)
                 }else{
                     if(t && this.direction){
@@ -320,7 +321,12 @@ class PanoRenderer extends THREE.EventDispatcher{
                 e.uploadQueued = !0 
                 this.uploadInterval || this.uploadIntervalCancelled || this.refreshUploadInterval(0)
             }
-             
+            
+            
+            
+            /* i ? this.uploadTile(e, !1) : (this.shoulPushToFrontOfQueue(e) ? this.forceQueue.push(e) : t && this.direction ? TilePrioritizer.insertSortedPanoTile(r, e, n.pano, this.direction) : r.push(e),
+                e.uploadQueued = !0,
+                this.uploadInterval || this.uploadIntervalCancelled || this.refreshUploadInterval(0)) */
         }
     }
 
@@ -381,21 +387,17 @@ class PanoRenderer extends THREE.EventDispatcher{
             (!i || i && i === r.tile.panoId) && r.level >= t ? (r.uploadQueued = !1,
                 e.splice(n, 1)) : n++
         }
-        //若报错, r.tile.panoId改为 r.panoId
     }
 
-        
-    updateUploadQueue(maxNPF,maxPF/* e, t */) {//参数是 maxNonBaseUploadsPerFrame and maxBaseUploadsPerFrame, 优先上传512
-        maxNPF || (maxNPF = 1);
+
+    updateUploadQueue(e, t) {
+        e || (e = 1);
         for (var i = 0, n = 0;;) {
-            let old = this.forceQueue.slice(0)
-           
-            if (n >= maxPF || i >= maxNPF)
+            if (n >= t || i >= e)
                 break;
             var r = this.getNextFromUploadQueue();
             if (!r)
                 break;
-            //r.panoSize <2048 && console.log('panoId', r.panoId, 'panoSize', r.panoSize , old)
             0 !== r.level ? i++ : n++
             if (!(r.panoSize > this.qualityManager.getMaxNavPanoSize()) || this.zoomingActive) {
                 var o = this.getActiveRenderTargetDescriptor(r.panoId);
@@ -483,8 +485,7 @@ class PanoRenderer extends THREE.EventDispatcher{
             if (t.hasOwnProperty(i)) {
                 var n = t[i];
                 n.uploadCount = 0,
-                n.uploadAttempts = 0  
-                n.uploaded = [] 
+                    n.uploadAttempts = 0
             }
     }
 
@@ -493,8 +494,7 @@ class PanoRenderer extends THREE.EventDispatcher{
             n = i[t];
         return n || (n = {
                     uploadCount: 0,
-                    uploadAttempts: 0, 
-                    uploaded:[],//add
+                    uploadAttempts: 0
                 },
                 i[t] = n),
             n
@@ -797,12 +797,12 @@ PanoRenderer.prototype.renderPanoTiles = function () {
         for (var a = 0; a < TileUtils.FACES_PER_PANO; a++) {
             var s = this.getTileTree(panoId, a);
             e.length = 0 
-            s.breadthFirst({//获取所有node?  85个
+            s.breadthFirst({//获取所有node?
                 saveVisited: e
             });
             for (var l = 0; l < e.length; l++) {
                 var c = e[l];
-                this.queueTileUpload(c.tile, !1, r || 0 === l && n)//为什么第0个会直接uploadTile??
+                this.queueTileUpload(c.tile, !1, r || 0 === l && n)//???
             }
         }
         this.updateDirection(i)
@@ -853,7 +853,7 @@ PanoRenderer.prototype.uploadTile = function () {//重写
     var collection = {},
         overlayStyle = config.tiling.overlayStyle;
         
-    var failHistory = {};    
+        
         
     return function (info, n) {
         
@@ -867,7 +867,6 @@ PanoRenderer.prototype.uploadTile = function () {//重写
             tileY = info.tileY,
             p = !0,
             g = !1,
-            ignore = false, //add   
             LodDescripor = (this.getPanoDescriptor(id), this.getPanoLODDescriptor(id, panoSize)),
             activeDescripor = this.getActiveRenderTargetDescriptor(id),
             renderTarget = activeDescripor.renderTarget,
@@ -879,37 +878,15 @@ PanoRenderer.prototype.uploadTile = function () {//重写
             size =  this.zoomRenderTarget.width   //this.qualityManager.getMaxZoomPanoSize(); //放大后可能2048或4096
         } 
         
-        let done = ()=>{ 
-            if(!LodDescripor.uploaded.includes(tileIndex)){//已经upload过(本来这时候直接返回,但发现缩放后这不会归零,导致清晰度不更新,所以还是redraw且emit吧)
-                //console.log('try to reupload and return',tileIndex) 
-                LodDescripor.uploaded.push(tileIndex)
-                LodDescripor.uploadCount++;
-            }   
-            this.dispatchEvent({type:PanoRendererEvents.TileRenderSuccess, id, panoSize, tileIndex, totalTiles});
-            LodDescripor.uploadCount === totalTiles && this.dispatchEvent({type:PanoRendererEvents.PanoRenderComplete, id, panoSize, totalTiles, updateFullComplete:true});
-            this.setUploaded(info, !0);
-            this.addCoverageForNode(info.node);
-        }
-        
         
         
-        {//已经uploadTile过了不再uploadTile
-            if(!this.isRenderTargetDescriptorValid(activeDescripor)){
-                p = !1; g = !1
-            } 
-            if(!n){
-                this.anyUploaded(info.node) && (p = !1, g = !0,ignore = true  ) //包括子集也uploadTile了
-                this.isTileUploaded(info) && (p = !1, g = !1,ignore = true ) //当前tile uploadTile了 
-            }
-        }
         
         
+        this.isRenderTargetDescriptorValid(activeDescripor) || (p = !1, g = !1),
+            n || (this.anyUploaded(info.node) && (p = !1, g = !0),
+                this.isTileUploaded(info) && (p = !1, g = !1));
         if (p) {
-             
-            /*if(failHistory[id+':'+ panoSize+ ':' +tileIndex]){
-                console.log('uploadTile retry',id, panoSize, tileIndex)
-            } 
-            console.log('uploadTile 成功', id, panoSize, tileIndex) */  
+              
 
             var C = tileX * tileSize,
                 I = tileY * tileSize,
@@ -939,29 +916,18 @@ PanoRenderer.prototype.uploadTile = function () {//重写
                     this.renderToCubeMap(tex, renderTarget, tileSize, tileSize, 0, 0, tileSize, tileSize, b, w, E, E, info.cubeFace);
                 }
             }
-            done()
-           
-        }else if(ignore){ 
-            //console.log('finish because anyUploaded',id,panoSize,tileIndex)
-            done() //改: 如果因为这部分更高清的贴图已加载所以才不绘制的话,直接完成
-            
-        }else{
-            //console.log('uploadTile  失败', id, panoSize, tileIndex)
-            if(panoSize == 512){
-                //console.log("!!!!!!!!!!!!!")
-            } 
             
-            failHistory[id+':'+ panoSize+ ':' +tileIndex] = true;   
-            this.setUploaded(info, !1); 
+            LodDescripor.uploadCount++;
+            this.emit(PanoRendererEvents.TileRenderSuccess, id, panoSize, tileIndex, totalTiles);
+            LodDescripor.uploadCount === totalTiles && this.emit(PanoRendererEvents.PanoRenderComplete, id, panoSize, totalTiles);
+            this.setUploaded(info, !0);
+            this.addCoverageForNode(info.node);
+        } else {
+            this.setUploaded(info, !1);
         }
-
-
-
-
-
-        info.uploadAttempted || (LodDescripor.uploadAttempts++, this.dispatchEvent({type:PanoRendererEvents.TileUploadAttempted, id, panoSize, tileIndex, totalTiles})),
-        info.uploadAttempted = !0;
-        LodDescripor.uploadAttempts === totalTiles && this.dispatchEvent({type:PanoRendererEvents.UploadAttemptedForAllTiles, id, panoSize, totalTiles});
+        info.uploadAttempted || (LodDescripor.uploadAttempts++, this.emit(PanoRendererEvents.TileUploadAttempted, id, panoSize, tileIndex, totalTiles)),
+            info.uploadAttempted = !0;
+        LodDescripor.uploadAttempts === totalTiles && this.emit(PanoRendererEvents.UploadAttemptedForAllTiles, id, panoSize, totalTiles);
         return g;
     }
 }()
@@ -988,7 +954,7 @@ PanoRenderer.prototype.renderToCubeMap = function() {
         plane = null,
         l = 1;
     return function(texture, renderTarget, tileWidth, tileHeight, startXinTile, startYinTile, widthinTile, heightinTile, startX, startY, width, height, cubeFace, E, b, w) {
-         
+        
           
         var renderer =  this.viewer.renderer; 
         
@@ -1064,8 +1030,7 @@ PanoRenderer.prototype.renderToCubeMap = function() {
         renderer.properties.get(scene); 
         material.uniforms.tDiffuse.value = texture;
         material.blending = E || THREE.NoBlending,
-        material.transparent = !!b 
-        
+        material.transparent = !!b,
         void 0 !== w && null !== w || (w = 1),
         material.uniforms.alpha.value = w,
         material.needUpdate = !0  
@@ -1082,10 +1047,6 @@ PanoRenderer.prototype.renderToCubeMap = function() {
         var oldTarget = renderer.getRenderTarget();
         renderer.autoClear = !1
         
-        
-         
-         
-        
         renderer.setRenderTarget(renderTarget, cubeFace);
         renderer.render(scene, camera/* , renderTarget, !1 */);  
         renderer.setRenderTarget(oldTarget)
@@ -1186,12 +1147,10 @@ PanoRenderer.prototype.copyCubeMap = function() {//将texture渲染到zoomRender
 
 
 
-/* 
-forceQueue在tiledownloader和panorenderer都有。
-forceQueue 的应该就是优先下载的吧,按理说一定要先下载完才能下载后面的在 
-在panoRenderer中 uploadQueues 是候补队列 ,在tileDownloader里priorityQueue是候补队列
-tiledownloader下载完成会触发tiledownloader开始uploadTile.
- */
+
+
+
+
 
 
 export default PanoRenderer

+ 4 - 4
src/modules/Images360/tile/QualityManager.js

@@ -1,9 +1,9 @@
 
 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'
+import browser from '../../../utils/browser' 
+import {settings,config} from '../../../settings'
+import {ModelManagerEvents,PanoSizeClass} from '../../../defines'
 
 
 
@@ -116,7 +116,7 @@ export default class QualityManager {
             return PanoSizeClass.STANDARD
         }
         return PanoSizeClass.HIGH  */
-        switch(Potree.settings.navTileClass){  
+        switch(config.navTileClass){  
             case '1k':
                 return PanoSizeClass.STANDARD;
                 break;

+ 127 - 135
src/modules/Images360/tile/TileDownloader.js

@@ -1,24 +1,17 @@
-import {TileDownloaderEvents, DownloadStatus} from '../../../defines.js'
+import {TileDownloaderEvents, DownloadStatus} from '../../../defines'
 import * as THREE from "../../../../libs/three.js/build/three.module.js";
  
-import TilePrioritizer from './TilePrioritizer.js'
-import TileUtils from './TileUtils.js'
+import TilePrioritizer from './TilePrioritizer'
+import TileUtils from './TileUtils'
  
  
-import {settings, config} from '../../../settings.js' 
+import {settings, config} from '../../../settings' 
 import {
     http
-} from '../../../utils/request.js' 
+} from '../../../utils/request'
+import { EventDispatcher } from "../../../EventDispatcher.js";
 
-
-
-window.downloaded = {}
-window.startdownloads = [];
-
-
-
-
-class TileDownloader extends THREE.EventDispatcher{
+class TileDownloader extends EventDispatcher{
     constructor( ) {
         super()
         this.panos = null;
@@ -39,14 +32,7 @@ class TileDownloader extends THREE.EventDispatcher{
             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() 
-        }) 
+
          
     }
 
@@ -55,36 +41,15 @@ class TileDownloader extends THREE.EventDispatcher{
         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()
-        } 
+    start() {
+        this.started = true //add
+        this.refreshUpdateInterval(0)
     }
 
-    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)
-        }
-        
+    stop() {
+        this.started = false
+        window.clearTimeout(this.refreshInterval)
     }
 
     refreshUpdateInterval(e) {
@@ -96,20 +61,15 @@ class TileDownloader extends THREE.EventDispatcher{
                 .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)
+    update() {
+        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
     }
 
     
@@ -174,27 +134,12 @@ class TileDownloader extends THREE.EventDispatcher{
 
             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++
-                }
-                
+                o && (this.startDownload(o),
+                    n++)
             }
         }
-    } 
-    
-    
-    
-    
+    }
+ 
     testDownload(panoSize, tileSize, callback) {
         var n = this.downloadTestResults[panoSize];
         if (n)
@@ -216,10 +161,6 @@ class TileDownloader extends THREE.EventDispatcher{
     }
 
     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;
@@ -247,25 +188,15 @@ class TileDownloader extends THREE.EventDispatcher{
                 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))
+                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))
         //}
     }
 
@@ -351,11 +282,7 @@ class TileDownloader extends THREE.EventDispatcher{
     
 
     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}`    
+        return `https://4dkk.4dage.com/images/images${sceneNum}/${d}`    
     }
 
     loadImage(e, t, i, n) {
@@ -378,24 +305,16 @@ TileDownloader.prototype.forceQueueTilesForPano = function() {//根据条件开
             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;) {  //过滤掉不符合角度要求的
+                    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++){
+        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);
@@ -435,7 +354,7 @@ TileDownloader.prototype.getTileUrl = function() {
             panoSize = o.panoSize,
             tileSize = o.tileSize,
             tileIndex = o.tileIndex,
-            sceneCode = o.pano.pointcloud.sceneCode
+            datasetName = o.pano.pointcloud.name
         var metadata = {sceneScheme:10}  
         
         
@@ -445,17 +364,9 @@ TileDownloader.prototype.getTileUrl = function() {
             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) 
+        1 === config.tiling.customCompression && (u = "_" + config.tiling["q" + e[panoSize]]);
+         
+        /* if (metadata.sceneScheme == 10)  */{//阿里云oss的规则
             
             d = 'tiles/4k/' + id + '_skybox' + h + '.jpg?x-oss-process=';
             if (e[panoSize] == '512') {
@@ -468,7 +379,7 @@ TileDownloader.prototype.getTileUrl = function() {
                     d = 'tiles/4k/' + id + '_skybox' + h + '.jpg?x-oss-process=image/crop,w_512,h_512,';
                 }
                 //起始位置
-                if (t.tileX == 0) {
+                /* if (t.tileX == 0) {
                     d += 'x_0,';
                 } else {
                     d += 'x_' + (512 * t.tileX - 1) + ',';
@@ -478,14 +389,95 @@ TileDownloader.prototype.getTileUrl = function() {
                     d += 'y_0';
                 } else {
                     d += 'y_' + (512 * t.tileY - 1);
-                } 
+                } */
+                
+                if (t.tileX == 0) {
+                    d += 'x_1,';
+                } else {
+                    d += 'x_' + (512 * t.tileX) + ',';
+                }
+
+                if (t.tileY == 0) {
+                    d += 'y_1';
+                } else {
+                    d += 'y_' + (512 * t.tileY);
+                }
+                
+                
+                
             }
             
-            d = this.getTiles(d, sceneCode);
+            d = this.getTiles(d, datasetName);
             g = "&" 
         } 
         
-        d += g + 'time='+o.pano.pointcloud.timeStamp  //加后缀
+         
+        
+        /* //8目
+        else if (metadata.sceneScheme == 11) {
+            //阿里云oss的规则 
+            d = 'tiles/2k/' + id + '_skybox' + h + '.jpg?x-oss-process=';
+            if (e[panoSize] == '512') {
+                d += 'image/resize,h_512';
+            } else {
+                //移动端是1k,pc端是2k
+                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/2k/' + 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, datasetName); 
+            g = "&" 
+        }
+        //双目,随心装等
+        else if (metadata.sceneScheme == 12) {
+            //阿里云oss的规则 
+            d = 'tiles/1k/' + id + '_skybox' + h + '.jpg?x-oss-process=';
+            if (e[panoSize] == '512') {
+                d += 'image/resize,h_512';
+            } else {
+                d = 'tiles/1k/' + 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, datasetName); 
+            g = "&" 
+        }
+        else {//国际版 
+            //var d = this.getTiles("tiles/" + id + "/" + e[panoSize] + u + "_face" + h + "_" + t.tileX + "_" + t.tileY + ".jpg");
+            d = this.getTiles("tiles/" + id + "/" + e[panoSize]  + "_face" + h + "_" + t.tileX + "_" + t.tileY + ".jpg", datasetName);
+            //return d = ab.changeIfTileGenerating(d)
+            g = "?"  
+            
+        }
+          */
+          
+        /* if(typeof(this.store.getters['scene/metadata'].imagesVersion)!='undefined'){
+            d+= g +'imagesVersion='+this.store.getters['scene/metadata'].imagesVersion
+        }  */
          
         return d;
     }

+ 32 - 64
src/modules/Images360/tile/TilePrioritizer.js

@@ -1,10 +1,10 @@
  
-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 {DownloadStatus} from '../../../defines'
+import {Images360} from '../Images360'
+import TileUtils from './TileUtils'
+import cameraLight from '../../../utils/cameraLight'
+import math from '../../../utils/math'
+import Common from '../../../utils/Common' 
 import * as THREE from "../../../../libs/three.js/build/three.module.js";
 
 
@@ -171,7 +171,7 @@ TilePrioritizer.appendQueue = function (e, t) {
 };
 
 TilePrioritizer.sortPanoTiles = function (descriptors, pano, dir) {
-    if(dir.datasetsLocal)  dir = dir.datasetsLocal.find(e=>e.datasetId == pano.pointcloud.dataset_id).direction;//add
+    if(dir instanceof Array)  dir = dir.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)
@@ -180,7 +180,7 @@ TilePrioritizer.sortPanoTiles = function (descriptors, pano, dir) {
 };
 
 TilePrioritizer.insertSortedPanoTile = function (e, t, pano, dir) {
-    if(dir.datasetsLocal)  dir = dir.datasetsLocal.find(e=>e.datasetId == pano.pointcloud.dataset_id).direction;//add
+    if(dir instanceof Array)  dir = dir.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),
@@ -202,45 +202,23 @@ TilePrioritizer.insertSortedPanoTile = function (e, t, pano, dir) {
 };
 
 
-
-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 (有点复杂,没看很懂)
+TilePrioritizer.prototype.filterAndPrioritize = function () {//挑选出优先加载的  (有点复杂,没看很懂)
     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)  
-        
         
+         
+        let cameraDirLocals = this.priorityCriteria.cameraDirs.map(e=>{ //add
             return {
                 datasetId:e.datasetId,
-                direction: direction.clone().applyMatrix4(matrix)
+                direction: math.convertVector.YupToZup(e.direction)
             }
-        }) */
-        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
+        }) 
+        //let cameraDirLocals = math.convertVector.YupToZup(this.priorityCriteria.cameraDirs)
         
+        this.populateScoredPanos(this.priorityCriteria.pano, panos, t, cameraDirLocals , TilePrioritizer.MAX_SCORED_PANOS_TOCONSIDER);
         var s = this.baseSize //512
             ,
             l = this.standardSize //1024
@@ -248,59 +226,49 @@ TilePrioritizer.prototype.filterAndPrioritize = function () {//挑选出优先
             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.queueTilesForPano(queue, tileDownloader, this.priorityCriteria.pano, s);
+        if (this.priorityCriteria.upcomingPanos) {//即将走到的,之前用于导览路线
             this.queueTilesForPanos(queue, this.priorityCriteria.upcomingPanos, tileDownloader, s, TilePrioritizer.MAX_UPCOMING_PANOS_TOADD);
         }
         i.length = 0;
-        
-        //把当前pano角度范围内的tile按照分辨率从低到高加入队列
-        
-        if (this.canDownloadSize(l)) {//1024如果在限制范围内的话
+        if (this.canDownloadSize(l)) {//l没超过最大size限制的话
             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.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
+        if (this.canDownloadSize(c)) {
             this.queueTilesInDirectionForPano(i, tileDownloader, this.priorityCriteria.pano, c, this.priorityCriteria.cameraPosition, this.priorityCriteria.cameraDirs, TilePrioritizer.DIRECTIONAL_FOV_NARROW);
         }
 
-        if (this.canDownloadSize(h)) {//4096
+        if (this.canDownloadSize(h)) {
             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.sortPanoTiles(i, this.priorityCriteria.pano, this.priorityCriteria.cameraDirs);
         TilePrioritizer.appendQueue(queue, i);
         i.length = 0;
 
-        if (this.canDownloadSize(l)) {//1024
+        if (this.canDownloadSize(l)) {
             this.queueTilesInDirectionForPano(i, tileDownloader, this.priorityCriteria.pano, l, this.priorityCriteria.cameraPosition, this.priorityCriteria.cameraDirs, TilePrioritizer.DIRECTIONAL_FOV);
         }
 
-        if (this.canDownloadSize(c)) {//2048
+        if (this.canDownloadSize(c)) {
             this.queueTilesInDirectionForPano(i, tileDownloader, this.priorityCriteria.pano, c, this.priorityCriteria.cameraPosition, this.priorityCriteria.cameraDirs, TilePrioritizer.DIRECTIONAL_FOV);
         }
 
-        if (this.canDownloadSize(h)) {//4096
+        if (this.canDownloadSize(h)) {
             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.sortPanoTiles(i, this.priorityCriteria.pano, this.priorityCriteria.cameraDirs);
         TilePrioritizer.appendQueue(queue, i);
-        
-        
-        
-        this.queueTilesForPanos(queue, e, tileDownloader, s); // 如果前面有populateNeighborPanos的话,这步就是加neibour
+        this.queueTilesForPanos(queue, e, tileDownloader, s);
     }
 }()
 TilePrioritizer.prototype.queueTilesInDirectionForPano = function () {
@@ -312,7 +280,7 @@ TilePrioritizer.prototype.queueTilesInDirectionForPano = function () {
         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.find(e=>e.datasetId == pano.pointcloud.dataset_id).direction;//add
         //var dir = dirs
         
         t.copy(dir);

+ 2 - 3
src/modules/Images360/tile/TileUtils.js

@@ -1,5 +1,5 @@
-import {GLCubeFaces} from '../../../defines.js'
-import MathLight from '../../../utils/MathLight.js'
+import {GLCubeFaces} from '../../../defines'
+import MathLight from '../../../utils/MathLight'
 import * as THREE from "../../../../libs/three.js/build/three.module.js";
 
 
@@ -111,7 +111,6 @@ TileUtils.getTileLocation = function(size, t, result) {
     result.tileY = Math.floor(l / a);
     result.face = r;
     result.faceTileIndex = l;
-    return result
 }
 ,
 

+ 2 - 1
src/modules/OrientedImages/OrientedImageControls.js

@@ -1,8 +1,9 @@
 
 import * as THREE from "../../../libs/three.js/build/three.module.js";
+import {EventDispatcher} from "../../EventDispatcher.js";
 
  
-export class OrientedImageControls extends THREE.EventDispatcher{
+export class OrientedImageControls extends EventDispatcher{
 	
 	constructor(viewer){
 		super();

+ 3 - 2
src/modules/OrientedImages/OrientedImages.js

@@ -1,6 +1,7 @@
 
 import * as THREE from "../../../libs/three.js/build/three.module.js";
-import {OrientedImageControls} from "./OrientedImageControls.js"; 
+import {OrientedImageControls} from "./OrientedImageControls.js";
+import { EventDispatcher } from "../../EventDispatcher.js";
 
 // https://support.pix4d.com/hc/en-us/articles/205675256-How-are-yaw-pitch-roll-defined
 // https://support.pix4d.com/hc/en-us/articles/202558969-How-are-omega-phi-kappa-defined
@@ -118,7 +119,7 @@ export class OrientedImage{
 
 };
 
-export class OrientedImages extends THREE.EventDispatcher{
+export class OrientedImages extends EventDispatcher{
 
 	constructor(){
 		super();

+ 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 {EventDispatcher} from "../../EventDispatcher.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: new EventDispatcher,
-    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

+ 24 - 198
src/modules/clipModel/Clip.js

@@ -1,32 +1,16 @@
 import * as THREE from "../../../libs/three.js/build/three.module.js";
-import {BoxVolume} from '../../objects/tool/Volume.js'
+import {BoxVolume} from '../../utils/Volume'
 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 {mapClipBox} from '../../utils/mapClipBox'
+import Common from '../../utils/Common'
+import {Images360} from '../Images360/Images360'
+
 
 const defaultBoxWidth = 6;  //navvis:  10
-                            //navvis position: si {x: 0, y: 0, z: 0}
-   
-var Clip = {
-    bus : new THREE.EventDispatcher,
-    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)  
-        } 
-    },
+                           //navvis position: si {x: 0, y: 0, z: 0}
 
+var Clip = {
+   
     enter:function(){
         this.previousView = { 
 			position: viewer.images360.position,
@@ -36,16 +20,11 @@ var Clip = {
             ifShowMarker : Potree.settings.ifShowMarker,
             
 		} 
-
-        let pointcloud = this.getPointcloud() 
-        let bound = pointcloud.bound //只选取其中一个数据集的bound,而非整体,是因为担心两个数据集中间有空隙,于是刚好落在没有点云的地方。
+        let bound = viewer.scene.pointclouds[0].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 eyeDir = scale.clone().setZ(boundSize.z/3).multiplyScalar(1.3) 
         let position = new THREE.Vector3().addVectors(target, eyeDir)
         
         Potree.settings.displayMode = 'showPointCloud'
@@ -74,24 +53,21 @@ var Clip = {
                 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.mapBox.updatePoints(scale) 
             })
             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;
@@ -103,7 +79,6 @@ var Clip = {
                 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() 
@@ -112,12 +87,10 @@ var Clip = {
                 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()
             })
         }
         
@@ -131,40 +104,11 @@ var Clip = {
         
         Potree.settings.unableNavigate = true
         Potree.settings.ifShowMarker = false
-        viewer.updateVisible(viewer.measuringTool.scene, 'clipModel', false)   
-        //viewer.updateVisible(viewer.mapViewer.cursor, 'clipModel', false)//隐藏地图游标
+        viewer.updateVisible(viewer.measuringTool.scene, '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(){
@@ -177,48 +121,17 @@ var Clip = {
         Potree.settings.unableNavigate = false
         Potree.settings.ifShowMarker = this.previousView.ifShowMarker
         viewer.updateVisible(viewer.measuringTool.scene, 'clipModel', true)  
-        //viewer.updateVisible(viewer.mapViewer.cursor, 'clipModel', true) 
+        
         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)
-        }
-        
+        var pano = Common.find(viewer.images360.panos , [], [Images360.sortFunctions.floorDistanceToPoint(cameraPos)]);
+        target.copy(pano.position) 
+        target.setZ(boundCenter.z)
         return target
     },
     /* switchMap:function(state){
@@ -226,115 +139,28 @@ var Clip = {
         
     }, */
     
-    download:function( ){
-        
-        if(this.getIntersectPointcloud().length == 0){
-            return null
-        }
-        
-        
+    download:function(){
         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, 
+                return {
+                    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
-         
-        
-        
+        //https://testlaser.4dkankan.com/indoor/t-ia44BhY/api/pointcloud/crop
     },
     
-    
     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界面显示全部平面图,按楼层切换显示。 
-     */
-    
 }
 
 

+ 48 - 259
src/modules/datasetAlignment/Alignment.js

@@ -1,201 +1,42 @@
 
 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 SplitScreen from "../../utils/SplitScreen"
+import math from "../../utils/math"
+
+
 
 var Alignment = {
-    SplitScreen: SplitScreen4Views, 
+    SplitScreen, 
     handleState:null,  //操作状态 'translate'|'rotate'
-    bus: new THREE.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   
+        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))
-                
-                
+                Alignment.translate(e.pointcloud,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})
-                    
+                 
+                let center = e.pointcloud.translateUser //移动到的位置就是中心
+                if(!rotateInfo){
+                    rotateInfo = {
+                        orientationUser : e.pointcloud.orientationUser,
+                        vecStart : new THREE.Vector3().subVectors(e.intersectStart, center).setZ(0),
+                        pointcloud: e.pointcloud
+                    } 
                 }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)
-                    }
-                }    
+                    let vec = new THREE.Vector3().subVectors(e.intersectPoint, 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() 
-            } 
+            rotateInfo = null
         })
-        
-        
     },
     
     
@@ -211,9 +52,6 @@ var Alignment = {
         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())
         
         
@@ -229,31 +67,8 @@ var Alignment = {
             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观察这样做是绕同一个点旋转的)
+    rotate:function(pointcloud, deg, angle){//假设点云位移position后0,0,0就是它的中心了(根据navvis观察这样做是绕同一个点旋转的)
         var angle = angle != void 0 ? angle : THREE.Math.degToRad(deg)   //正逆负顺
         pointcloud.orientationUser += angle
         Alignment.setMatrix(pointcloud)
@@ -263,57 +78,44 @@ var Alignment = {
         Alignment.setMatrix(pointcloud)
     },
     
-    
-    
-    
+    saveTemp:function(){//记录最近一次保存后的状态,便于恢复
+        this.originData = viewer.scene.pointclouds.map(e=>{
+            return {
+                id : e.dataset_id,
+                orientationUser : e.orientationUser,
+                translateUser : e.translateUser.clone(),
+            }
+        } )
+    },
     enter:function(){
-        //this.saveTemp()  
-        this.originData = this.getTemp() 
+        this.saveTemp()  
         
-        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};
         
+        SplitScreen.splitScreen4Views({alignment:true})
+        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=>{//恢复
+        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)
-        }) 
+        
+        SplitScreen.recoverFrom4Views()
+        
         this.editing = false
-        this.history.clear() 
-        viewer.updateFpVisiDatasets()
-        viewer.dispatchEvent({
-            type : "CursorChange", action : "remove",  name:"movePointcloud" 
-        })
-        viewer.dispatchEvent({
-            type : "CursorChange", action : "remove",  name:"rotatePointcloud" 
-        })
+        
+         
+        
     } 
     
     ,
@@ -326,19 +128,14 @@ var Alignment = {
         viewer.dispatchEvent({
             type : "CursorChange", action : "remove",  name:"rotatePointcloud" 
         })
-        
-        this.bus.dispatchEvent({type:'switchHandle' , state })
-        
-        
-
     },
     
     
     save: function(){//保存所有数据集的位置和旋转
         let callback = ()=>{//保存成功后
-            this.originData = this.getTemp()   //this.saveTemp();
+            this.saveTemp();
             //需要修改 测量线的position。漫游点已经实时修改了
-            
+            viewer.updateModelBound();
             viewer.scene.measurements.forEach(e=>e.transformByPointcloud())
             viewer.images360.updateCube(viewer.bound)
         }
@@ -354,7 +151,8 @@ var Alignment = {
                 //transformMatrix: e.transformMatrix.elements,
             }
         })
-        //data = JSON.stringify(data)
+        data = data[0]//暂时只传第一个
+        
         
         //test: 退出后保留结果
         if(!Potree.settings.isOfficial){
@@ -367,15 +165,6 @@ var Alignment = {
     
 }
 
-
-Alignment.history = new History({ 
-    callback: (data)=>{ 
-        data.forEach(item=>{
-            Alignment.applyTemp(item)  
-        }) 
-    } 
-})
-
 /* 
 
 关于控制点:

+ 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"
-
- 
-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 THREE.EventDispatcher(), 
-     
-    
-    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到模型上开始转动的一瞬间很卡。
-
-
-
-
-
-*/ 

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 0 - 1227
src/modules/panoEdit/panoEditor.js


+ 132 - 660
src/modules/siteModel/BuildingBox.js

@@ -1,410 +1,126 @@
 
 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 {ctrlPolygon} from '../../utils/ctrlPolygon'
+import {LineDraw, MeshDraw } from "../../utils/DrawUtil";
+import Sprite from '../../viewer/Sprite'
 /* 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 markerSizeInfo = {width2d:30}
 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]
-}
 
 
+let faceMats = {
+    building: new THREE.MeshPhongMaterial({
+        color:"#00bbff",
+        side:THREE.DoubleSide,
+        opacity:0.1,
+        transparent:true,
+        depthTest:false
+    }),
+    floor:  new THREE.MeshPhongMaterial({
+        color:"#eeee00",
+        side:THREE.DoubleSide,//BackSide,
+        opacity:0.06,
+        transparent:true,
+        depthTest:false
+    }),
+    floorSelect: new THREE.MeshPhongMaterial({
+        color:"#eeee00",
+        side:THREE.DoubleSide,
+        opacity:0.15,
+        transparent:true,
+        depthTest:false
+    }),
+    room: new THREE.MeshPhongMaterial({
+        color:"#ff44ee",
+        side:THREE.DoubleSide,//BackSide,
+        opacity:0.06,
+        transparent:true,
+        depthTest:false
+    }),
+    roomSelect: new THREE.MeshPhongMaterial({
+        color:"#ff44ee",
+        side:THREE.DoubleSide,//BackSide,
+        opacity:0.15,
+        transparent:true,
+        depthTest:false
+    }),
+    
+}
+
 
- 
 
 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);
-        
-         
-        
+        super('siteModel_'+prop.type_,  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'){
+        if(this.type_=='floor'){//一旦添加了楼层,建筑原本的faceMesh lineMesh就隐藏
+            /* this.buildParent.box.visible = false 
+            this.buildParent.lineMesh.visible = false  */
             
-            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//完全等于建筑的点
-            })
+            this.points = this.buildParent.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.box = this.createBox()
+        this.add(this.box)
         
-        this.initData(prop)
+        this.lineMesh = LineDraw.createLine([],{color})
+        this.lineMesh.name = 'buildingLines'        
+        this.add(this.lineMesh) 
+        viewer.setObjectLayers(this.lineMesh, 'sceneObjects' )
         
+        this.buildChildren = []//子实体
         
-    } 
-    
-    
-    initData(prop){
-        if(prop.ifDraw){
-            super.initData(prop) 
-        }else{
-            if(prop.points){
-                this.points = prop.points  
-            }
-            
-            
-        }
+        this.addEventListener('dragChange',(e)=>{ //修改中点
+            this.isNew || this.updateTwoMidMarker(e.index)
+        })
+   
         
     } 
     
-    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)
+        var mesh = new THREE.Mesh(geometry, faceMats[this.type_])
         mesh.name = 'buildingBox';
-        if(this.buildType == 'floor'){
-            viewer.setObjectLayers(mesh, 'siteModelMapUnvisi' ) //楼层默认在地图不显示,为了不会叠加透明度
+        if(this.type_ == 'floor'){
+            viewer.setObjectLayers(mesh, 'siteModelMapUnvisi' )
         }else{
-            viewer.setObjectLayers(mesh, 'bothMapAndScene' )
+            viewer.setObjectLayers(mesh, 'sceneObjects' )
         }
-         
-        
-        
-        //mesh.frustumCulled = false;
         return mesh
     }
     
     
     
     addMarker(o={} ){
-        if(this.buildType=='floor')return; //楼层不需要marker
+        if(this.type_=='floor')return; //楼层不需要marker
         
-        let marker = new Sprite({mat:this.getMarkerMaterial('default'), renderOrder : 3, sizeInfo: markerSizeInfo, dontFixOrient: true, name:"building_marker"} )
-       
+        let marker = new Sprite({mat:this.getMarkerMaterial('default'), sizeInfo: markerSizeInfo, dontFixOrient: true, name:"building_marker"} )
+        
+        marker.renderOrder = 3 
          
         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
+        if(this.type_=='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)]
         
@@ -413,23 +129,23 @@ export class BuildingBox extends ctrlPolygon{//建筑实体,包括building, fl
         viewer.setObjectLayers(marker, 'siteModeOnlyMapVisi' ) 
         { // Event Listeners  
             let mouseover = (e) => {
-                this.setMarkerSelected(e.object, 'hover', 'single'); 
+                this.setMarkerSelected(e.object, true, 'single');
                 viewer.dispatchEvent({
                     type : "CursorChange", action : "add",  name:"markerMove"
                 }) 
             };
             let mouseleave = (e) => {
-                this.setMarkerSelected(e.object, 'unhover', 'single');
+                this.setMarkerSelected(e.object, false, '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()  }) 
+                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') 
+                this.setMarkerSelected(marker, false) 
                 viewer.inputHandler.startDragging(newMarker , {/* dragViewport:viewer.mapViewer.viewports[0],  */   } ); //notPressMouse代表不是通过按下鼠标来拖拽.  dragViewport指定了只能在地图上拖拽
             }
             marker.addEventListener('drag', drag );
@@ -439,14 +155,11 @@ export class BuildingBox extends ctrlPolygon{//建筑实体,包括building, fl
         }
         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)=>{
@@ -457,7 +170,6 @@ export class BuildingBox extends ctrlPolygon{//建筑实体,包括building, fl
     }
     
     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位置
@@ -470,84 +182,35 @@ export class BuildingBox extends ctrlPolygon{//建筑实体,包括building, fl
         this.updateMarker(nextMidMarker, nextMid) 
     }
     
-     
-    
-    
-    
-    dispose(){//销毁geo、remove from parent
+    dispose(){
         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 
-            }
-             
-        }
+        this.box.geometry.dispose();
+        this.lineMesh.geometry.dispose();
+        
+        
+        this.buildChildren.forEach(e=>e.dispose())
     }
     
-     
-    
-    update(options={}){ 
-        super.update(this.buildType != 'floor' && options.ifUpdateMarkers)
-        let length = this.points.length
+    update(ifUpdateMarkers, dontUpdateChildren){ 
+        super.update(ifUpdateMarkers)
         
         
-       
-        {//确保一下一样
-            if(this.originHole){ 
-                this.points = this.originHole.points //完全等于building的hole
-            }
-            if(this.buildType == 'hole'){
-                this.zMin = this.buildParent.zMin;
-                this.zMax = this.buildParent.zMax;
-            } 
+        this.box.geometry.dispose()
+        let length = this.points.length 
+        if(length >= 3){ 
+            this.box.geometry = MeshDraw.getExtrudeGeo(this.points, this.zMax-this.zMin) 
+            this.box.position.z = this.zMin
         }
         
-        
-        
-        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()
+       /*  if(!this.isNew){
+            this.midMarkers
         }
-        
-        
+         */
         
         {//update lines
-            
+            //let zMin = 0, zMax = 1
             let positions = [];
-           
+            
             this.points.forEach((point, index)=>{
                 
                 //竖线:
@@ -555,126 +218,41 @@ export class BuildingBox extends ctrlPolygon{//建筑实体,包括building, fl
                 
                 //横线
                 let nextPoint = this.points[(index+1)%length]; 
-                if(!nextPoint)return;//when length==1
+                if(point == 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)
-            
+        if(this.type_ == 'building' && !dontUpdateChildren){
+            this.buildChildren.forEach(e=>{
+                e.points = this.points
+                e.update()
+            })
             
-        }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
+    removeMarker(index ){  
+        super.removeMarker(index) 
+        this.update(); 
+        if(this.points.length == 2){//清除原先length>=3时候的
+            this.box.geometry = new THREE.Geometry();
         }
-        return {zMin,zMax}
+        //this.dispatchEvent({type: 'marker_removed', measurement: this});
     }
     
     
-    /* 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 = {  
@@ -693,17 +271,9 @@ export class BuildingBox extends ctrlPolygon{//建筑实体,包括building, fl
                     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'),
+                    color,
                     opacity: 1,
                     map: texLoader.load(Potree.resourcePath+'/textures/whiteCircle.png' ), 
                     depthTest:false,
@@ -719,161 +289,63 @@ export class BuildingBox extends ctrlPolygon{//建筑实体,包括building, fl
     
     setMarkerSelected(marker, state, hoverObject){ 
         //console.warn(marker.id , state, hoverObject)
-         
-        
-        if(state == 'select'){
-            marker.selected = true
+        if(state){
             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')
-                } 
-            }
+            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'){
+        if(this.type_ == 'building'){
             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' )
+            
+        }else if(this.type_ == 'floor'){
+            
+            this.box.material = faceMats.floorSelect
+            viewer.setObjectLayers(this.box, 'sceneObjects' )
+             
+        }else if(this.type_ == 'room'){
+            this.box.material = faceMats.roomSelect
         }
-        
-        
-        
-        
-        
         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=>{  //(这里要保证选中前要先取消选中,否则如选中房间后取消了楼层,房间线就隐藏了)
+        if(this.type_ == 'building'){ 
+            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' )
+        }else if(this.type_ == 'floor'){ 
+            viewer.setObjectLayers(this.box, 'siteModelMapUnvisi' )
+            this.box.material = faceMats.floor
+        }else if(this.type_ == 'room'){
+            this.box.material = faceMats.room
         }
-        
         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)]
-    }
-}
- 
+}

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 294 - 1001
src/modules/siteModel/SiteModel.js


+ 3 - 2
src/navigation/DeviceOrientationControls.js

@@ -14,9 +14,10 @@
  *
  */
 
-import * as THREE from "../../libs/three.js/build/three.module.js"; 
+import * as THREE from "../../libs/three.js/build/three.module.js";
+import {EventDispatcher} from "../EventDispatcher.js";
 
-export class DeviceOrientationControls extends THREE.EventDispatcher{
+export class DeviceOrientationControls extends EventDispatcher{
 	constructor(viewer){
 		super();
 

+ 24 - 23
src/navigation/EarthControls.js

@@ -1,9 +1,10 @@
 
 import * as THREE from "../../libs/three.js/build/three.module.js";
-import {Buttons} from "../defines.js";
-import {Utils} from "../utils.js"; 
+import {MOUSE} from "../defines.js";
+import {Utils} from "../utils.js";
+import {EventDispatcher} from "../EventDispatcher.js";
 
-export class EarthControls extends THREE.EventDispatcher {
+export class EarthControls extends EventDispatcher {
 	constructor (viewer) {
 		super(viewer);
 
@@ -50,12 +51,12 @@ export class EarthControls extends THREE.EventDispatcher {
 			let view = this.viewer.scene.view;
 
 			// let camera = this.viewer.scene.camera;
-			let Buttons = e.drag.end;
+			let mouse = e.drag.end;
 			let domElement = this.viewer.renderer.domElement;
 
-			if (e.drag.Buttons === Buttons.LEFT) {
+			if (e.drag.mouse === MOUSE.LEFT) {
 
-				let ray = Utils.ButtonsToRay(this.viewer.inputHandler.pointer/* Buttons */, camera, domElement.clientWidth, domElement.clientHeight);
+				let ray = Utils.mouseToRay(this.viewer.inputHandler.pointer/* mouse */, camera, domElement.clientWidth, domElement.clientHeight);
 				let plane = new THREE.Plane().setFromNormalAndCoplanarPoint(
 					new THREE.Vector3(0, 0, 1),
 					this.pivot);
@@ -81,10 +82,10 @@ export class EarthControls extends THREE.EventDispatcher {
 						this.viewer.setMoveSpeed(speed);
 					}
 				}
-			} else if (e.drag.Buttons === Buttons.RIGHT) {
+			} else if (e.drag.mouse === MOUSE.RIGHT) {
 				let ndrag = {
-					x: e.drag.ButtonsDelta.x / this.renderer.domElement.clientWidth,
-					y: e.drag.ButtonsDelta.y / this.renderer.domElement.clientHeight
+					x: e.drag.mouseDelta.x / this.renderer.domElement.clientWidth,
+					y: e.drag.mouseDelta.y / this.renderer.domElement.clientHeight
 				};
 
 				let yawDelta = -ndrag.x * this.rotationSpeed * 0.5;
@@ -114,9 +115,9 @@ export class EarthControls extends THREE.EventDispatcher {
 			}
 		};
 
-		let onButtonsDown = e => {
-			let I = Utils.getButtonsPointCloudIntersection(
-				e.Buttons, 
+		let onMouseDown = e => {
+			let I = Utils.getMousePointCloudIntersection(
+				e.mouse, 
 				this.scene.getActiveCamera(), 
 				this.viewer, 
 				this.scene.pointclouds, 
@@ -134,7 +135,7 @@ export class EarthControls extends THREE.EventDispatcher {
 			this.dispatchEvent({type: 'end'});
 		};
 
-		let onButtonsUp = e => {
+		let onMouseUp = e => {
 			this.camStart = null;
 			this.pivot = null;
 			this.pivotIndicator.visible = false;
@@ -145,14 +146,14 @@ export class EarthControls extends THREE.EventDispatcher {
 		};
 
 		let dblclick = (e) => {
-			this.zoomToLocation(e.Buttons);
+			this.zoomToLocation(e.mouse);
 		};
 
 		this.addEventListener('drag', drag);
 		this.addEventListener('drop', drop);
-		this.addEventListener('Buttonswheel', scroll);
-		this.addEventListener('Buttonsdown', onButtonsDown);
-		this.addEventListener('Buttonsup', onButtonsUp);
+		this.addEventListener('mousewheel', scroll);
+		this.addEventListener('mousedown', onMouseDown);
+		this.addEventListener('mouseup', onMouseUp);
 		this.addEventListener('dblclick', dblclick);
 	}
 
@@ -165,11 +166,11 @@ export class EarthControls extends THREE.EventDispatcher {
 		this.zoomDelta.set(0, 0, 0);
 	}
 	
-	zoomToLocation(Buttons){
+	zoomToLocation(mouse){
 		let camera = this.scene.getActiveCamera();
 		
-		let I = Utils.getButtonsPointCloudIntersection(
-			Buttons,
+		let I = Utils.getMousePointCloudIntersection(
+			mouse,
 			camera,
 			this.viewer,
 			this.scene.pointclouds);
@@ -183,7 +184,7 @@ export class EarthControls extends THREE.EventDispatcher {
 			let minimumJumpDistance = 0.2;
 
 			let domElement = this.renderer.domElement;
-			let ray = Utils.ButtonsToRay(this.viewer.inputHandler.pointer, camera, domElement.clientWidth, domElement.clientHeight);
+			let ray = Utils.mouseToRay(this.viewer.inputHandler.pointer, camera, domElement.clientWidth, domElement.clientHeight);
 
 			let nodes = I.pointcloud.nodesOnRay(I.pointcloud.visibleNodes, ray);
 			let lastNode = nodes[nodes.length - 1];
@@ -236,8 +237,8 @@ export class EarthControls extends THREE.EventDispatcher {
 		
 		// compute zoom
 		if (this.wheelDelta !== 0) {
-			let I = Utils.getButtonsPointCloudIntersection(
-				this.viewer.inputHandler.Buttons, 
+			let I = Utils.getMousePointCloudIntersection(
+				this.viewer.inputHandler.mouse, 
 				this.scene.getActiveCamera(), 
 				this.viewer, 
 				this.scene.pointclouds);

+ 109 - 344
src/navigation/FirstPersonControls.js

@@ -14,12 +14,15 @@
  */
 
 import * as THREE from "../../libs/three.js/build/three.module.js";
-import {Buttons} from "../defines.js";
-import {Utils} from "../utils.js"; 
-import cameraLight from "../utils/cameraLight.js"; 
-import Common from "../utils/Common.js"; 
+import {MOUSE} from "../defines.js";
+import {Utils} from "../utils.js";
+import {EventDispatcher} from "../EventDispatcher.js";
+import cameraLight from "../utils/cameraLight.js";
+
+
  
-export class FirstPersonControls extends THREE.EventDispatcher {
+
+export class FirstPersonControls extends EventDispatcher {
 	constructor (viewer, viewport) {
 		super();
         
@@ -56,15 +59,14 @@ export class FirstPersonControls extends THREE.EventDispatcher {
 
         };
 
-		this.fadeFactor = 20;
+		this.fadeFactor = 50;
 		this.yawDelta = 0;
 		this.pitchDelta = 0;
 		this.translationDelta = new THREE.Vector3(0, 0, 0);
 		this.translationWorldDelta = new THREE.Vector3(0, 0, 0);
 
 		this.tweens = [];
-        this.dollyStart = new THREE.Vector2
-        this.dollyEnd = new THREE.Vector2
+
         //this.enableChangePos = true
         
         this.viewer.addEventListener('camera_changed',(e)=>{
@@ -74,23 +76,10 @@ export class FirstPersonControls extends THREE.EventDispatcher {
 
 		let drag = (e) => {
             if(!this.enabled)return 
-            let viewport = e.dragViewport;
+            let viewport = e.drag.dragViewport;
             if(!viewport)return
             let camera = viewport.camera 
-            let mode 
-            if(e.isTouch){
-                if(e.touches.length == 1){
-                    mode = (!e.dragViewport || e.dragViewport.name == 'MainView') ? 'rotate' : 'pan' 
-                }else if(e.touches.length == 2){
-                    mode = 'scale'
-                }else{
-                    mode = (!e.dragViewport || e.dragViewport.name == 'MainView') ? 'pan' : 'scale' 
-                } 
-            }else{
-                //mode = e.buttons === Buttons.LEFT && (!e.dragViewport || e.dragViewport.name == 'MainView') ? 'rotate' : 'pan'
-                mode = e.buttons === Buttons.LEFT && camera.type != 'OrthographicCamera' ? 'rotate' : 'pan'
-            }
-            //console.log('mode  ', mode )
+            let mode = e.drag.mouse === MOUSE.LEFT && (!e.drag.dragViewport || e.drag.dragViewport.name == 'MainView') ? 'rotate' : 'pan'
             let moveSpeed = this.currentViewport.getMoveSpeed();
             if (e.drag.startHandled === undefined) {///???????
 				e.drag.startHandled = true;
@@ -98,139 +87,58 @@ export class FirstPersonControls extends THREE.EventDispatcher {
 				this.dispatchEvent({type: 'start'});
 			}
             
-                
-            if (mode.includes('rotate')) {//旋转 
+			if (mode == 'rotate') {//旋转   (为什么开启调试时旋转很慢?)
 				
                 //来自panoramaControl updateRotation
-                if(!this.pointerDragStart){
-                   return this.pointerDragStart = e.pointer.clone()
-                }
-                
                 
+                let _matrixWorld = camera.matrixWorld
+                camera.matrixWorld = new THREE.Matrix4;//unproject 前先把相机置于原点 
                 
-                let view = this.scene.view;
-                if(Potree.settings.rotAroundPoint && this.intersectStart && this.canMovePos(viewport) && !viewer.images360.isAtPano() && !this.viewer.inputHandler.pressedKeys[17]){//定点旋转:   以当前intersect的点为target旋转,不改点在屏幕中的位置
-                    let distance = camera.position.distanceTo(this.intersectStart.location)                                               //不按下ctrl的话                 
-                      
-                    //按照orbitControl的方式旋转:
-                    let rotationSpeed = 2.5;  
-                    
-                    this.yawDelta -= e.drag.pointerDelta.x * rotationSpeed;
-                    this.pitchDelta += e.drag.pointerDelta.y * rotationSpeed;
-
+                var e1 = new THREE.Vector3(e.drag.pointerDragStart.x,e.drag.pointerDragStart.y,-1).unproject(camera)
+                  , t = new THREE.Vector3(e.drag.pointer.x,e.drag.pointer.y,-1).unproject(camera)
+                  , i = Math.sqrt(e1.x * e1.x + e1.z * e1.z)
+                  , n = Math.sqrt(t.x * t.x + t.z * t.z)
+                  , o = Math.atan2(e1.y, i)
+                  , a = Math.atan2(t.y, n);
                    
-                    //先更新一下相机:    
-                    this.update() 
-                    view.applyToCamera(camera)
-                    
-                    //然后得到新的相机角度下,原先点在屏幕中的位置所对应的3d点现在的坐标。只需要平移一下新旧坐标差值即可。
-                    let newPointerDir = viewer.inputHandler.getMouseDirection(this.intersectStart.pointer).direction.clone().multiplyScalar(distance)
-                    let pivot = new THREE.Vector3().addVectors(camera.position, newPointerDir)  //新的3d点
-                     
-                    let moveVec = new THREE.Vector3().subVectors(pivot, this.intersectStart.location)
-                     
-                    this.translationWorldDelta.copy(moveVec.negate()) 
-                    //立即更新下,防止因update和此drag频率不同而打滑。
-                    this.update()
-                    view.applyToCamera(camera)
-                    
-               
-                }else{
-                  
-                    
-                    let _matrixWorld = camera.matrixWorld
-                    camera.matrixWorld = new THREE.Matrix4;//unproject 前先把相机置于原点 
-                    
-                    var e1 = new THREE.Vector3(this.pointerDragStart.x,this.pointerDragStart.y,-1).unproject(camera)
-                      , t = new THREE.Vector3(e.pointer.x,e.pointer.y,-1).unproject(camera)
-                      , i = Math.sqrt(e1.x * e1.x + e1.z * e1.z)
-                      , n = Math.sqrt(t.x * t.x + t.z * t.z)
-                      , o = Math.atan2(e1.y, i)
-                      , a = Math.atan2(t.y, n);
-                       
-                    this.pitchDelta +=  o - a  //上下旋转
-                    e1.y = 0,
-                    t.y = 0; 
-                    
-                    var s = Math.acos(e1.dot(t) / e1.length() / t.length());
-                    
-                    if(!isNaN(s)){
-                        var yawDelta = s    //左右旋转 
-                        this.pointerDragStart.x > e.pointer.x && (yawDelta *= -1) 
-                        this.yawDelta += yawDelta
-                    } 
-                    
-                    
-                    //console.log('rotate:', this.pitchDelta, e.pointer.toArray(), this.pointerDragStart.toArray())
-                    
-                    
-                    this.pointerDragStart.copy(e.pointer)
-                     
-                    camera.matrixWorld = _matrixWorld ;
-                    
+                this.pitchDelta +=  o - a  //上下旋转
+                e1.y = 0,
+                t.y = 0; 
                 
+                var s = Math.acos(e1.dot(t) / e1.length() / t.length());
                 
+                if(!isNaN(s)){
+                    var yawDelta = s    //左右旋转 
+                    e.drag.pointerDragStart.x > e.drag.pointer.x && (yawDelta *= -1) 
+                    this.yawDelta += yawDelta
                 } 
-			} 
-            
-            if (mode.includes('pan')) {//平移 
-                if(!this.canMovePos(viewport)){
-                    return
-                } 
-                
+                e.drag.pointerDragStart.copy(e.drag.pointer)
+                 
+                camera.matrixWorld = _matrixWorld ;
+              
+			} else if (mode == 'pan') {//平移 
+                if(viewport.unableChangePos)return
                 if(camera.type == "OrthographicCamera"){
                    
-                    //console.log(e.drag.pointerDelta, e.pointer, e.drag.end)
-                    let moveVec = Utils.getOrthoCameraMoveVec(e.drag.pointerDelta, camera )//最近一次移动向量
-                  
-                    let pointclouds;
-                    let Alignment = window.viewer.modules.Alignment
-                    let MergeEditor = window.viewer.modules.MergeEditor
-                    let handleState = Alignment.handleState
                     
-                    let a = e.buttons === Buttons.LEFT && viewport.alignment && handleState && viewport.alignment[handleState] 
-                    if(Potree.settings.editType == 'pano'){//右键平移视图、左键操作点云 
-                        let PanoEditor = window.viewer.modules.PanoEditor
-                             
-                        if(a && PanoEditor.selectedPano){
-                            if(!PanoEditor.selectedGroup || !PanoEditor.checkIfAllLinked({group:PanoEditor.selectedGroup}) ){
-                                if(handleState == 'translate' && ( e.drag.intersectStart.pointclouds && Common.getMixedSet(PanoEditor.selectedClouds, e.drag.intersectStart.pointclouds).length  || PanoEditor.selectedPano.hovered)//拖拽到点云上 或 circle
-                                    || handleState == 'rotate' ) 
-                                {  
-                                    pointclouds = PanoEditor.selectedClouds
-                                }  
-                            }else{
-                                PanoEditor.dispatchEvent('needToDisConnect')
-                                console.warn('选中的漫游点连通了整个数据集,不允许移动')
-                            } 
-                        }
-                        
-                        if(!pointclouds && e.buttons === Buttons.LEFT && viewport.rotateSide){
-                            return PanoEditor.rotateSideCamera(-e.drag.pointerDelta.x)
-                        }
-                    }else if(Potree.settings.editType == 'merge'){ 
-                        if(e.buttons === Buttons.LEFT && viewport.rotateSide){ 
-                            return MergeEditor.rotateSideCamera(-e.drag.pointerDelta.x)
-                        }  
+                    /* let ViewWidthPX = viewport.width * viewer.renderer.domElement.clientWidth
+                    let ViewHeightPX = viewport.height * viewer.renderer.domElement.clientHeight
+                    let cameraViewWidth = camera.right * 2
+                    let cameraViewHeight = camera.top * 2; 
+                     
+                    moveVec.set(-1 * e.drag.mouseDelta.x * cameraViewWidth / ViewWidthPX, e.drag.mouseDelta.y * cameraViewHeight / ViewHeightPX , 0).applyQuaternion(camera.quaternion)  
+                     */
                     
-                    }else{ 
-                        /* if(Alignment.selectedClouds && Alignment.selectedClouds.length){
-                            pointclouds = a && e.drag.intersectStart.pointclouds && Common.getMixedSet(Alignment.selectedClouds, e.drag.intersectStart.pointclouds).length && Alignment.selectedClouds
-                            
-                        }else{ */
-                            pointclouds = a && e.drag.intersectStart.pointcloud && [e.drag.intersectStart.pointcloud]
-                        //}
-                        
-                    }
-                      
-                    if(pointclouds){
+                    let moveVec = Utils.getOrthoCameraMoveVec(e.drag.pointerDelta, camera )//最近一次移动向量
+                    
+                    let handleState = window.viewer.modules.Alignment.handleState
+                    if(viewport.alignment && handleState && viewport.alignment[handleState] && e.drag.intersectStart.pointcloud){
                         this.dispatchEvent({
                             type : "transformPointcloud", 
-                            intersect: e.intersect.orthoIntersect,   
+                            intersectPoint: e.intersectPoint.orthoIntersect,   
                             intersectStart: e.drag.intersectStart.orthoIntersect,
                             moveVec,        
-                            pointclouds, 
-                            camera
+                            pointcloud: e.drag.intersectStart.pointcloud,
                         }) 
                     }else{ 
                         
@@ -242,41 +150,32 @@ export class FirstPersonControls extends THREE.EventDispatcher {
                     
                 }else{  
                     if(e.drag.intersectStart){//如果拖拽着点云 
-                        
+                         
                         if(e.drag.z == void 0){//拖拽开始
                             let pointerStartPos2d = e.drag.intersectStart.location.clone().project(camera);//识别到的点云点的位置
                             e.drag.z = pointerStartPos2d.z //记录z,保持拖拽物体到屏幕距离不变,所以z深度不变
                             e.drag.projectionMatrixInverse = camera.projectionMatrixInverse.clone()
                             //防止吸附到最近点上(因为鼠标所在位置并非识别到的点云点的位置,需要得到鼠标所在位置的3d坐标。)
-                            let pointerStartPos2dReal = new THREE.Vector3(this.pointerDragStart.x,this.pointerDragStart.y, e.drag.z);
+                            let pointerStartPos2dReal = new THREE.Vector3(e.drag.pointerDragStart.x,e.drag.pointerDragStart.y, e.drag.z);
                             e.drag.translateStartPos = pointerStartPos2dReal.clone().unproject(camera);
                             /* this.viewer.dispatchEvent({ 
                                 type: 'dragPanBegin', 
                                 projectionMatrixInverse : e.drag.projectionMatrixInverse
                             }); */
-                            //console.log('开始拖拽', e.pointer.clone())
                         }  
                         //拖拽的过程中将projectionMatrixInverse替换成开始拖拽时的,因为near、far一直在变,会导致unproject计算出的3d坐标改变很大而闪烁。
                         var _projectionMatrixInverse = camera.projectionMatrixInverse;
                         camera.projectionMatrixInverse = e.drag.projectionMatrixInverse;
                         
                         
-                        let newPos2d = new THREE.Vector3(e.pointer.x,e.pointer.y,   e.drag.z );
+                        let newPos2d = new THREE.Vector3(e.drag.pointer.x,e.drag.pointer.y,   e.drag.z );
                         let newPos3d = newPos2d.clone().unproject(camera);
                         let moveVec = newPos3d.clone().sub( e.drag.translateStartPos  /*  e.drag.intersectStart.location  */ );//移动相机,保持鼠标下的位置永远不变,所以用鼠标下的新位置减去鼠标下的原始位置
                         
                       
                         camera.projectionMatrixInverse = _projectionMatrixInverse
                         this.translationWorldDelta.copy(moveVec.negate())  //这里没法用add,原因未知,会跳动
-                        //console.log('pan 1', this.translationWorldDelta.clone())   
-                        
-                         
-                        
-                        //四指松开剩三指时会偏移一下,暂不知道哪里的问题,或许跟开头防止点云吸附有关?
-                        
-                        
-                        
-                        
+                          
                     }else{ //如果鼠标没有找到和点云的交点,就假设移动整个模型(也可以去扩大范围寻找最近点云)
                          
                         /* let center = viewer.scene.pointclouds[0].position;
@@ -291,123 +190,63 @@ export class FirstPersonControls extends THREE.EventDispatcher {
                         }  */
                         let lastIntersect = viewport.lastIntersect ? (viewport.lastIntersect.location || viewport.lastIntersect) : viewer.bound.center  //该viewport的最近一次鼠标和点云的交点
                         let speed = camera.position.distanceTo(lastIntersect)   
-                        let fov = cameraLight.getHFOVForCamera(camera, true)
-                        let ratio = speed  * Math.tan(fov/2) 
+                        let fov = cameraLight.getHFOVForCamera(camera, camera.aspect, 1)
+                        let ratio = speed  * Math.tan(THREE.Math.degToRad(fov)/2) 
                         this.translationDelta.x -= e.drag.pointerDelta.x  * ratio
                         this.translationDelta.z -= e.drag.pointerDelta.y  * ratio 
-                         //console.log('pan2', e.drag.pointerDelta)
+                         
+                         
+                    
                     }
                 } 
-                this.useAttenuation = false
-			}
-            
-            
-            if(mode.includes('scale')){
- 
-                this.dollyEnd.subVectors(e.touches[0].pointer, e.touches[1].pointer);
-                //if(!this.dollyStart)return
-                var scale = this.dollyEnd.length() / this.dollyStart.length()
-
-                //console.log('scale ',scale)
-                 
-                let pointer = new THREE.Vector2().addVectors(e.touches[0].pointer, e.touches[1].pointer).multiplyScalar(0.5);//两个指头的中心点
                 
-                dolly({
-                    pointer,
-                    scale, camera
-                })
-                this.dollyStart.copy(this.dollyEnd);
-                
-            }
+			}
             //最好按ctrl可以变为dollhouse的那种旋转
 		};
 
 		let drop = e => {
             if(!this.enabled)return    
 			this.dispatchEvent({type: 'end'});
-            
 		};
 
-
-        let dolly = (e={})=>{
-                       
-            if(Potree.settings.displayMode == 'showPanos' && this.currentViewport == viewer.mainViewport/* this.currentViewport.unableChangePos */){//全景时 
-                this.dispatchEvent({type:'dollyStopCauseUnable',delta:e.delta, scale:e.scale})
-                return 
-            }
-            
-            let camera = e.camera
-            
-            
+		let scroll = (e) => {
+            if(!this.enabled)return   
+            this.setCurrentViewport(e)            
+            if(this.currentViewport.unableChangePos)return 
+            let camera = e.hoverViewport.camera
+            let speed = this.currentViewport.getMoveSpeed() || 1 
             if(camera.type == "OrthographicCamera"){
                 let ratio
-                if(e.delta != void 0){//滚轮缩放
-                    if(e.delta == 0){//mac
-                       return 
-                    }else if (e.delta < 0) {
-                        ratio = 0.9 
-                    } else if (e.delta > 0) {
-                        ratio = 1.1
-                    } 
-                }else{
-                    ratio = e.scale //触屏缩放
-                }
-                
+                if(e.delta == 0){//mac
+                   return 
+                }else if (e.delta < 0) {
+                    ratio = 0.9 
+                } else if (e.delta > 0) {
+                    ratio = 1.1
+                } 
                 let zoom = camera.zoom * ratio
-                let limit = camera.zoomLimit
-                if(limit) zoom = THREE.Math.clamp(zoom, limit.min,limit.max )
-                
-                
-                let pointerPos = new THREE.Vector3(e.pointer.x, e.pointer.y,0.5); 
-                let oldPos = pointerPos.clone().unproject(camera);
+                let limit = Potree.config.OrthoCameraLimit.zoom
+                zoom = THREE.Math.clamp(zoom, limit.min,limit.max )
                 
                 if(camera.zoom != zoom){ 
                     camera.zoom = zoom
                     camera.updateProjectionMatrix()
                 }
-                let newPos = pointerPos.clone().unproject(camera);
                 
-                //定点缩放, 恢复一下鼠标所在位置的位置改变量
-                let moveVec = new THREE.Vector3().subVectors(newPos,oldPos)
-                this.translationWorldDelta.add(moveVec.negate()) 
-                this.useAttenuation = false
-            }else{
-                let speed , direction
-                 
+               
                 
-                if(e.delta != void 0){//滚轮缩放 
-                    speed =  this.currentViewport.getMoveSpeed() * 15
-                    
-                    //var direction = this.currentViewport.view.direction.clone();
-                    direction = this.viewer.inputHandler.getMouseDirection().direction  //定点缩放
-                 
-                    
-                    if(e.delta == 0){//mac
-                        return 
-                    }else if (e.delta < 0) {
-                        speed *= -1
-                    } 
-                }else{
-                    const constantDis =  this.currentViewport.getMoveSpeed() * 200 //constantDis = 10;//常量系数,当放大一倍时前进的距离。可以调整
-                    speed = (e.scale-1)*constantDis //触屏缩放
-                    //pointer = new THREE.Vector2().addVectors().multiplyScalar(0.5);//两个指头的中心点
-                    direction = this.viewer.inputHandler.getMouseDirection(e.pointer).direction  //定点缩放
+            }else{
+                var direction = this.currentViewport.view.direction.clone();
+            
+                var vec = direction.multiplyScalar(speed * 7)
+                if (e.delta < 0) {
+                    this.translationWorldDelta.copy(vec.negate())
+                } else if (e.delta > 0) {
+                    this.translationWorldDelta.copy(vec)
                 }
-                 
-                this.useAttenuation = true
-                var vec = direction.multiplyScalar(speed )
-                this.translationWorldDelta.copy(vec)
-                
             }
-        }
-
-		let scroll = (e) => {
-            if(!this.enabled || !e.hoverViewport)return 
-            this.setCurrentViewport(e)
             
-                
-            e.camera = e.hoverViewport.camera                
-            dolly(e) 
+            
 		};
 
 		let dblclick = (e) => { 
@@ -419,69 +258,11 @@ export class FirstPersonControls extends THREE.EventDispatcher {
 		};
 
 		this.viewer.addEventListener('global_drag', drag);
-        /* this.viewer.addEventListener('global_touchmove', (e)=>{ 
-            if(!this.enabled)return
-            if(e.touches.length>1){//单指的就触发上一句 
-                //console.log('global_touchmove' )
-                drag(e)
-            }
-        }); */
 		this.viewer.addEventListener('global_drop', drop);
 		this.viewer.addEventListener('global_mousewheel', scroll);
 		this.viewer.addEventListener('global_dblclick', dblclick);
         
-        
-        
-        let prepareScale = (e)=>{//触屏的scale 
-            this.dollyStart.subVectors(e.touches[0].pointer, e.touches[1].pointer);
-        }
-        let prepareRotate = (e)=>{ 
-            this.pointerDragStart = e.pointer.clone()  
-            this.intersectStart = e.intersect && e.intersect.location && {
-                location : e.intersect.location,
-                pointer :  e.intersect.location.clone().project(e.dragViewport.camera) //intersect点在屏幕中的位置
-            }
-            //console.log('prepareRotate' )
-        }
-        let preparePan = (e)=>{//触屏的pan点云    还是会偏移
-            this.pointerDragStart = e.pointer.clone() 
-              
-            e.drag.z = void 0  //清空    
-            drag(e) //触屏点击时更新的pointer直接用一次drag
-            //console.log('preparePan '   )
-        }
-        
-        this.viewer.addEventListener('global_mousedown'/* 'startDragging' */, (e)=>{
-            if(!this.enabled)return
-            this.setCurrentViewport(e)
-            prepareRotate(e) 
-        })
-        
-        
-        //注意,每次增减指头都会修改pointer,需要更新下状态
-        this.viewer.addEventListener('global_touchstart', (e)=>{
-            if(!this.enabled)return
-
-            if(e.touches.length==2){//只监听开头两个指头
-                prepareScale(e)
-            }else if(e.touches.length>=3){
-                preparePan(e)
-            }
-        })
-        this.viewer.addEventListener('global_touchend', (e)=>{
-            if(!this.enabled)return
-            if(e.touches.length==2){//停止平移,开始scale
-                prepareScale(e)
-            }else if(e.touches.length==1){//停止scale,开始rotate
-                prepareRotate(e)
-            }else if(e.touches.length>=3){//重新准备下平移(因为抬起的指头可能包含平移使用的数据),否则抬起时漂移
-                preparePan(e)
-            }
-        })
-       
-        
-        
-        
+        this.viewer.addEventListener('startDragging', this.setCurrentViewport.bind(this))
         /* this.viewer.addEventListener('enableChangePos', (e)=>{
             if(!this.enabled)return
             this.enableChangePos = e.canLeavePano 
@@ -490,11 +271,7 @@ export class FirstPersonControls extends THREE.EventDispatcher {
 
        
 	}
-    canMovePos(viewport){
-        if(viewport == viewer.mainViewport && (Potree.settings.displayMode == 'showPanos' 
-        || viewer.images360.bumping || viewer.images360.latestToPano))return false
-        else return true
-    }
+    
     setEnable(enabled){
         this.enabled = enabled;
          
@@ -522,19 +299,23 @@ export class FirstPersonControls extends THREE.EventDispatcher {
 
 
     setCurrentViewport(o={}){//add
-        if(!this.enabled && !o.force )return
+        if(!this.enabled && !o.force)return
         if(o.hoverViewport && this.currentViewport != o.hoverViewport ){
-            this.currentViewport = o.hoverViewport  
+            this.currentViewport = o.hoverViewport 
+            
+            if(this.currentViewport.camera.type == 'OrthographicCamera'){
+                this.lockElevationOri = true
+                this.lockRotation = true
+            }else{
+                this.lockElevationOri = false
+                this.lockRotation = false
+            }
+     
+     
+     
 			//this.viewer.setMoveSpeed(this.currentViewport.radius/100);
             this.setFPCMoveSpeed(this.currentViewport)
         }
-        if(this.currentViewport.camera.type == 'OrthographicCamera'){
-            this.lockElevationOri = true
-            this.lockRotation = true
-        }else{
-            this.lockElevationOri = false
-            this.lockRotation = false
-        }
     }
 
      
@@ -562,7 +343,7 @@ export class FirstPersonControls extends THREE.EventDispatcher {
 			camera,
 			this.viewer,
 			this.scene.pointclouds); */
-        var I = this.viewer.inputHandler.intersect
+        var I = this.viewer.inputHandler.intersectPoint
 		if (!I) {
 			return;
 		}
@@ -625,10 +406,10 @@ export class FirstPersonControls extends THREE.EventDispatcher {
 		}
 	}
 
-	update (delta=1) {
+	update (delta) {
         if(!this.enabled)return
  
-        //console.log('update')
+        
 		let view = this.currentViewport.view  
 
 		{ // cancel move animations on user input
@@ -676,7 +457,7 @@ export class FirstPersonControls extends THREE.EventDispatcher {
                 }
             }
         
-            if(this.canMovePos(this.currentViewport) && !this.lockKey){
+            if(!this.currentViewport.unableChangePos){
                 if(this.lockElevation){
                     let dir = view.direction;
                     dir.z = 0;
@@ -714,27 +495,19 @@ export class FirstPersonControls extends THREE.EventDispatcher {
                 } else if (moveDown) {
                     this.translationWorldDelta.z = -this.currentViewport.getMoveSpeed();
                 }
-                
-                
-                if(moveUp || moveDown || moveForward || moveBackward){
-                    this.useAttenuation = false
-                }
-                
             } 
 		}
 
 		{ // apply rotation
 			let yaw = view.yaw;
 			let pitch = view.pitch;
-             
-            
+
 			yaw += this.yawDelta /* * delta; */
 			pitch += this.pitchDelta/*  * delta; */
 
 			view.yaw = yaw;
 			view.pitch = pitch;
             
-
             
             this.yawDelta = 0
             this.pitchDelta = 0 
@@ -759,10 +532,7 @@ export class FirstPersonControls extends THREE.EventDispatcher {
 				this.translationWorldDelta.y /* * delta */,
 				this.translationWorldDelta.z /* * delta */
 			);
-             
-            
-            
-            //this.translationWorldDelta.set(0,0,0)
+            this.translationWorldDelta.set(0,0,0)
 		}
 
 		{ // set view target according to speed
@@ -777,17 +547,12 @@ export class FirstPersonControls extends THREE.EventDispatcher {
 		}
  
 
-        if(this.useAttenuation){ //只有滚轮缩放时开启
+        { // decelerate over time
 			let attenuation = Math.max(0, 1 - this.fadeFactor * delta);
-          
-			 /*this.yawDelta *= attenuation;
+			/* this.yawDelta *= attenuation;
 			this.pitchDelta *= attenuation; 
-			this.translationDelta.multiplyScalar(attenuation);*/
-			this.translationWorldDelta.multiplyScalar(attenuation);
-		}else{
-            
-            this.translationWorldDelta.set(0,0,0)
-            
-        }  
+			this.translationDelta.multiplyScalar(attenuation);
+			this.translationWorldDelta.multiplyScalar(attenuation);*/
+		}   
 	}
 };

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 447 - 846
src/navigation/InputHandler.js


+ 36 - 220
src/navigation/OrbitControls.js

@@ -14,13 +14,12 @@
  */
 
 import * as THREE from "../../libs/three.js/build/three.module.js";
-import {Buttons} from "../defines.js";
-import {Utils} from "../utils.js"; 
-
-let minRadius = 2
+import {MOUSE} from "../defines.js";
+import {Utils} from "../utils.js";
+import {EventDispatcher} from "../EventDispatcher.js";
 
  
-export class OrbitControls extends THREE.EventDispatcher{
+export class OrbitControls extends EventDispatcher{
 	
 	constructor(viewer){
 		super();
@@ -31,11 +30,9 @@ export class OrbitControls extends THREE.EventDispatcher{
 		this.scene = null;
 		this.sceneControls = new THREE.Scene();
 
-		this.rotationSpeed = 3;  //旋转速度
-        
-         
+		this.rotationSpeed = 5;
 
-		this.fadeFactor = 100;
+		this.fadeFactor = 20;
 		this.yawDelta = 0;
 		this.pitchDelta = 0;
 		this.panDelta = new THREE.Vector2(0, 0);
@@ -44,103 +41,39 @@ export class OrbitControls extends THREE.EventDispatcher{
 		this.doubleClockZoomEnabled = true;
 
 		this.tweens = [];
-        this.dollyStart = new THREE.Vector2
-        this.dollyEnd = new THREE.Vector2
-        
-        
-        this.keys = {
-            FORWARD: ['W'.charCodeAt(0), 38],
-            BACKWARD: ['S'.charCodeAt(0), 40],
-            LEFT: ['A'.charCodeAt(0), 37],
-            RIGHT: ['D'.charCodeAt(0), 39],
-            UP: ['Q'.charCodeAt(0)],
-            DOWN: ['E'.charCodeAt(0)], 
-        };
-        
-        
+
 		let drag = (e) => {
             if(!this.enabled)return
- 
-            let viewport = e.dragViewport;
-            if(!viewport || viewport.camera.type == "OrthographicCamera" )return
-            //let camera = viewport.camera 
-          
-
-
 			if (e.drag.object !== null) {
 				return;
 			}
-            let mode
-            
-            if(e.isTouch){
-               
-                if(e.touches.length == 1){
-                    mode = 'rotate'  
-                }else{  
-                    mode = 'scale-pan'
-                }  
-            }else{
-                mode = e.buttons === Buttons.LEFT ? 'rotate' : 'pan'
-            }
 
-
-
-
-            
 			if (e.drag.startHandled === undefined) {
-				e.drag.startHandled = true; 
+				e.drag.startHandled = true;
+
 				this.dispatchEvent({type: 'start'});
 			}
 
-			 
+			/* let ndrag = {
+				x: e.drag.mouseDelta.x / this.renderer.domElement.clientWidth,
+				y: e.drag.mouseDelta.y / this.renderer.domElement.clientHeight
+			}; */
             let ndrag = e.drag.pointerDelta.clone()//.add(new THREE.Vector2(1,1)).multiplyScalar(0.5)
             ndrag.y *= -1
 
-			if (mode == 'rotate') { 
-                 
+			if (e.drag.mouse === MOUSE.LEFT) {
 				this.yawDelta += ndrag.x * this.rotationSpeed;
 				this.pitchDelta += ndrag.y * this.rotationSpeed;
 
-				
-			} else if(mode == 'pan'){
-               
+				this.stopTweens();
+			} else if (e.drag.mouse === MOUSE.RIGHT) {
 				this.panDelta.x += ndrag.x;
 				this.panDelta.y += ndrag.y;
 
-				 
-			}else if(mode == 'scale-pan'){ //add
-                this.dollyEnd.subVectors(e.touches[0].pointer, e.touches[1].pointer); 
-                var scale = this.dollyEnd.length() / this.dollyStart.length() 
-                  
-                this.dollyStart.copy(this.dollyEnd); 
-                this.radiusDelta = (1-scale) * this.scene.view.radius 
-			  
-                //------------------------
-                //平移
-                let pointer = new THREE.Vector2().addVectors(e.touches[0].pointer, e.touches[1].pointer).multiplyScalar(0.5);//两个指头的中心点
-                 
-                let delta = new THREE.Vector2().subVectors(pointer, this.lastScalePointer)
-                delta.y *= -1
-                this.panDelta.add(delta)
-                
-                this.lastScalePointer = pointer.clone()
-                
-                
-                
-                //console.log('scale ',scale, this.radiusDelta)
-                
-            }
-            
-            this.stopTweens();
-            
-            
+				this.stopTweens();
+			}
 		};
-        
-        
-        
-         
-        
-        
+
 		let drop = e => {
             if(!this.enabled)return
 			this.dispatchEvent({type: 'end'});
@@ -149,9 +82,9 @@ export class OrbitControls extends THREE.EventDispatcher{
 		let scroll = (e) => {
             if(!this.enabled)return
 			let resolvedRadius = this.scene.view.radius + this.radiusDelta;
-            if(resolvedRadius < 0.1 && e.delta>0)return; //防止缩放太小,导致很慢
+
 			this.radiusDelta += -e.delta * resolvedRadius * 0.1;
-            
+
 			this.stopTweens();
 		};
 
@@ -222,40 +155,6 @@ export class OrbitControls extends THREE.EventDispatcher{
 		this.viewer.addEventListener('global_drop', drop);
 		this.viewer.addEventListener('global_mousewheel', scroll);
 		this.viewer.addEventListener('global_dblclick', dblclick);
-        this.viewer.addEventListener('global_touchmove', (e)=>{ 
-            if(e.touches.length>1){//单指的就触发上一句 
-                //console.log('global_touchmove' )
-                drag(e)
-            }
-        });
-        let prepareScale = (e)=>{//触屏的scale
-            this.dollyStart.subVectors(e.touches[0].pointer, e.touches[1].pointer);
-            this.lastScalePointer = new THREE.Vector2().addVectors(e.touches[0].pointer, e.touches[1].pointer).multiplyScalar(0.5);//两个指头的中心点
-              
-        }
-         
-        this.viewer.addEventListener('global_touchstart', (e)=>{
-            if(this.enabled && e.touches.length==2){//只监听开头两个指头
-                prepareScale(e)
-            }
-        })
-        /* this.viewer.addEventListener('global_touchend', (e)=>{
-            if(!this.enabled)return
-            if(e.touches.length==1){//停止scale,开始rotate
-                prepareRotate(e)
-                //this.pointerDragStart = null
-                //console.log('只剩一个', e.pointer.toArray())
-            }
-        }) */
-        
-        
-        this.viewer.addEventListener('focusOnObject',(o)=>{
-            if(o.position && o.CamTarget){
-                let distance = o.position.distanceTo(o.CamTarget)
-                if(distance < minRadius) minRadius = distance * 0.5 //融合页面当focus一个很小的物体时,需要将minRadius也调小
-            }
-        })
-        
 	}
 
 	setScene (scene) {
@@ -271,7 +170,7 @@ export class OrbitControls extends THREE.EventDispatcher{
 		this.panDelta.set(0, 0);
 	}
 	
-	/* zoomToLocation(mouse){
+	zoomToLocation(mouse){
         if(!this.enabled)return
 		let camera = this.scene.getActiveCamera();
 		
@@ -281,17 +180,17 @@ export class OrbitControls extends THREE.EventDispatcher{
 			this.viewer,
 			this.scene.pointclouds,
 			{pickClipped: true});
-         
+
 		if (I === null) {
 			return;
-		} 
+		}
 
 		let targetRadius = 0;
 		{
 			let minimumJumpDistance = 0.2;
 
 			let domElement = this.renderer.domElement;
-			let ray = Utils.mouseToRay(this.viewer.inputHandler.pointer , camera, domElement.clientWidth, domElement.clientHeight);
+			let ray = Utils.mouseToRay(this.viewer.inputHandler.pointer/* mouse */, camera, domElement.clientWidth, domElement.clientHeight);
 
 			let nodes = I.pointcloud.nodesOnRay(I.pointcloud.visibleNodes, ray);
 			let lastNode = nodes[nodes.length - 1];
@@ -334,37 +233,7 @@ export class OrbitControls extends THREE.EventDispatcher{
 
 			tween.start();
 		}
-	} */
-
-
-
-
-    
-    zoomToLocation(mouse){
-        let I = viewer.inputHandler.intersect;
-        
-        if(!I)return
-        
-        let object = I.object || I.pointcloud;
-        I = I.location
-        
-        
-        if(!I || !object)return;
-        
-        let dis = this.scene.view.position.distanceTo(I); 
-        
-        
-        let bound = object.boundingBox.clone().applyMatrix4(object.matrixWorld)
-        let size = bound.getSize(new THREE.Vector3); 
-        let len = size.length()
-         
-        let distance = THREE.Math.clamp(dis, 0.1, Math.max(len * 0.1, 3) );
-        
-        minRadius = distance
-        viewer.focusOnObject({ position:I }, 'point', null, {distance})
-        
-    }
-
+	}
 
 	stopTweens () {
 		this.tweens.forEach(e => e.stop());
@@ -375,46 +244,6 @@ export class OrbitControls extends THREE.EventDispatcher{
         if(!this.enabled)return
 		let view = this.scene.view;
 
-
-
-
-        { // accelerate while input is given
-			let ih = this.viewer.inputHandler;
-
-			let moveForward = this.keys.FORWARD.some(e => ih.pressedKeys[e]);
-			let moveBackward = this.keys.BACKWARD.some(e => ih.pressedKeys[e]);
-			let moveLeft = this.keys.LEFT.some(e => ih.pressedKeys[e]);
-			let moveRight = this.keys.RIGHT.some(e => ih.pressedKeys[e]);
-			let moveUp = this.keys.UP.some(e => ih.pressedKeys[e]);
-			let moveDown = this.keys.DOWN.some(e => ih.pressedKeys[e]);
-            
-             
-              
-            let px = 0 , py = 0, pz = 0
-            if(moveForward){
-                py = 1
-            }else if(moveBackward){
-                py = -1
-            }
-            
-            if(moveLeft){
-                px = -1
-            }else if(moveRight){
-                px = 1
-            }
-            if(moveUp){
-                pz = 1
-            }else if(moveDown){
-                pz = -1
-            }
-            
-            (px!=0 || py!=0 || pz!=0) && view.translate(px, py, pz, true); 
-             
-        }
-                
- 
-
-
 		{ // apply rotation
 			let progression = Math.min(1, this.fadeFactor * delta);
 
@@ -435,12 +264,9 @@ export class OrbitControls extends THREE.EventDispatcher{
 		}
 
 		{ // apply pan
-			/* let progression = Math.min(1, this.fadeFactor * delta);
-			let panDistance = progression * view.radius * 3; */
-            let camera = this.scene.getActiveCamera()
-            let panDistance = 2 * view.radius * Math.tan(THREE.Math.degToRad(camera.fov / 2));//参照4dkk。 平移target(也就是平移镜头位置),但还是难以保证跟手(navvis也不一定跟手,但是很奇怪在居中时中心点居然是跟手的,可能计算方式不同)
-            //计算了下确实是这么算的。 平移pivot。 
-            
+			let progression = Math.min(1, this.fadeFactor * delta);
+			let panDistance = progression * view.radius * 3;
+
 			let px = -this.panDelta.x * panDistance;
 			let py = this.panDelta.y * panDistance;
 
@@ -448,22 +274,15 @@ export class OrbitControls extends THREE.EventDispatcher{
 		}
 
 		{ // apply zoom
-			let progression = 1//Math.min(1, this.fadeFactor * delta);
-             
-            
-            
+			let progression = Math.min(1, this.fadeFactor * delta);
+
 			// let radius = view.radius + progression * this.radiusDelta * view.radius * 0.1;
 			let radius = view.radius + progression * this.radiusDelta;
-                      
+
 			let V = view.direction.multiplyScalar(-radius);
 			let position = new THREE.Vector3().addVectors(view.getPivot(), V);
-			
-            if(this.constantlyForward) {// 到达中心点后还能继续向前移动,也就是能推进中心点
-                if(radius < minRadius){  
-                    radius = minRadius
-                } 
-            }
-            view.radius = radius;            
+			view.radius = radius;
+
 			view.position.copy(position);
 		}
 
@@ -473,17 +292,14 @@ export class OrbitControls extends THREE.EventDispatcher{
 		}
 
 		{ // decelerate over time
-			/* let progression = Math.min(1, this.fadeFactor * delta);
+			let progression = Math.min(1, this.fadeFactor * delta);
 			let attenuation = Math.max(0, 1 - this.fadeFactor * delta);
 
 			this.yawDelta *= attenuation;
 			this.pitchDelta *= attenuation;
 			this.panDelta.multiplyScalar(attenuation);
 			// this.radiusDelta *= attenuation;
-			this.radiusDelta -= progression * this.radiusDelta; */
-            
-            //取消衰减,直接stop
-            this.stop()  
+			this.radiusDelta -= progression * this.radiusDelta;
 		}
 	}
 };

+ 628 - 0
src/navigation/PanoramaControls.js

@@ -0,0 +1,628 @@
+import math from '../util/math'
+import MouseButton from '../enum/MouseButton'
+import ControlEvents from '../enum/eventList/ControlEvents'
+import common from '../util/common'
+import Keys from '../enum/Keys'
+import config from '../../config';
+import transitions from '../util/transitions'
+import lerp from '../util/lerp'
+import easing from '../util/easing'
+import logger from '../../utils/logger'
+import settings from '../settings'
+import {objects} from '../base'
+
+export default class PanoramaControls extends EventEmitter {
+    //漫游模式相机控制器
+    /**
+     * 3D图形变换的坐标系 https://blog.csdn.net/CALL_LKC/article/details/81411034
+     * 功能:主要是在漫游模式下控制相机的方向(相机的移动只是做了事件触发,逻辑不在此)
+     *
+     * 原理: 
+     * @ 以camera本地坐标系作为参考建立球坐标系,有关球坐标系 https://en.wikipedia.org/wiki/Spherical_coordinate_system
+     * @ target作为camera的视点通过鼠标交互在球坐标系运动,然后调用THREE的API:camera.LookAt(target)校正相机方向
+     * 
+     * @param {*} camera 被控制的相机
+     */
+    constructor(camera, dom,player) {
+        super();
+        this.camera = camera; //被控制的相机
+        this.camera.controls = this;
+        this.player = player;
+
+
+        this.target = new THREE.Vector3(0, 0, 0); //相机视点,鼠标交互主要影响的对象
+        this.lookVector = new THREE.Vector3; //相机方向,以单位向量表示
+        this.lookSpeed = .05; //没发现下文用到???
+        this.rotationAcc = new THREE.Vector2; //旋转加速度
+        this.rotationSpeed = new THREE.Vector2; //旋转速度
+
+        /**
+         * 球坐标系的相关参数lat,lon 与 phi,theta 两种表示形式
+         * 注:少了半径参数,因为是用于约束相机的方向,半径长短在此没有意义,单位1即可,体现在方向向量lookVector上
+         */
+        this.lat = 0; //纬度,角度表示,直观
+        this.lon = 0; //经度,角度表示,直观
+        this.phi = 0; //phi,标准球坐标系的参数,弧度表示,用于进行直接计算
+        this.theta = 0; //theta,标准球坐标系的参数,弧度表示,用于进行直接计算
+
+
+        this.enabled = !1; //是否启用
+        this.locked = !1; //是否锁定,可能视角锁死但是其余功能仍在工作
+
+
+        /**
+         * 交互行为相关,有鼠标点击与触摸,点击或触摸的地方在此约定统称为交互点
+         */
+        this.pointer = new THREE.Vector2(0, 0); //交互点的屏幕坐标,有别于DOM坐标,在此存放NDC坐标。(NDC,三维常用坐标系,二维坐标,整个屏幕映射范围(-1,1),屏幕中心为原点,+Y朝上,+X朝右)
+        this.pointersLimit = 2; //触摸事件的触摸点的限制个数
+        this.pointers = []; //存储交互点的坐标
+
+
+
+        this.rotationHistory = [];
+        this.rotationDifference = new THREE.Vector2;
+        this.pointerDragOn = !1;
+        this.pointerDragStart = new THREE.Vector2(0, 0);
+        this.pinchDistance = 0;
+        this.moveStart = new THREE.Vector2;
+        this.moveTolerance = .01; //拖拽与点击两种交互行为通过鼠标移动距离的临界值来区分,即为此
+
+        //鼠标所交互的界面元素
+        this.dom = dom;
+		//固定垂直视角,许钟文
+		this.limitDownAngel = null;
+		this.insideLookLimitDown = null;
+    }
+
+    usable() {
+        return this.enabled && !this.locked
+    }
+
+    /**
+     * 根据新的方向向量计算所指向的球面坐标(lat,lon)
+     * 用到了标准的笛卡尔坐标系转球面坐标系的数学方法
+     * 注:THREE 的 Vector3 与 Spherical 两个数学类有互转的方法
+     * @param {THREE.Vector3} direction 
+     */
+    lookAt(aim, dir) {
+        var t = dir || this.camera.position.clone().sub(aim); //aim所指点的笛卡尔坐标系
+
+        /**
+         * 以下全为笛卡尔坐标->球座标,不多赘述
+         */
+        var i = Math.atan(t.z / t.x);
+        i += t.x < 0 ? Math.PI : 0;
+        i += t.x > 0 && t.z < 0 ? 2 * Math.PI : 0;
+        this.lon = THREE.Math.radToDeg(i) + 180;
+        var n = Math.sqrt(t.x * t.x + t.z * t.z),
+            o = Math.atan(t.y / n);
+        this.lat = -THREE.Math.radToDeg(o);
+    }
+
+    /**
+     * 许钟文  加  看向某个位置
+     * 逐渐看向某个位置 通过改变lon和lat
+     * @param {THREE.Vector3} aim 
+     * @param {THREE.Vector3} cameraPos 
+     * @param {JSON} option 
+     */
+    startLookAt(aim, cameraPos, option) {
+        var useLonLat = option && (option.lon != void 0 || option.lat != void 0);
+        if (!useLonLat) {
+            var e = cameraPos ? cameraPos.clone().sub(aim) : this.camera.position.clone().sub(aim),
+                o = Math.atan(e.z / e.x);
+            o += e.x < 0 ? Math.PI : 0,
+                o += e.x > 0 && e.z < 0 ? 2 * Math.PI : 0;
+            var lon = THREE.Math.radToDeg(o) + 180;
+            var n = Math.sqrt(e.x * e.x + e.z * e.z),
+                i = Math.atan(e.y / n);
+            var lat = -THREE.Math.radToDeg(i);
+
+            var add = (lon - this.lon) % 360;
+            Math.abs(add) > 180 && (add > 0 ? add -= 360 : add += 360);
+            lon = this.lon + add;
+            var add = (lat - this.lat) % 360;
+            Math.abs(add) > 180 && (add > 0 ? add -= 360 : add += 360);
+            lat = this.lat + add;
+        }
+        var time = 1200,
+            speedFuc = easing["easeInOutQuad"];
+        if (option != void 0) {
+            if (option.soon) {
+                this.lon = lon;
+                this.lat = lat;
+                return;
+            }
+            if (option.speed) {
+                /* var a = Math.abs(lon - this.lon) * Math.PI /180;
+                var b = Math.abs(lat - this.lat) * Math.PI /180;
+                var c0 = Math.sqrt(Math.pow(Math.sin(a/2),2) +  Math.pow(Math.sin(b/2),2));
+                var c = Math.asin(c0) * 2;	//得到旋转角度   cos(c/2)的方 = cos(a/2)的方 + cos(b/2)的方
+                time = c / option.speed; */
+                if (useLonLat) {
+                    var c1 = option.lon ? Math.abs(option.lon - this.lon) : 0;
+                    var c2 = option.lat ? Math.abs(option.lat - this.lat) : 0;
+                    var c = c1 + c2;
+                } else
+                    var c = Math.abs(lon - this.lon) + Math.abs(lat - this.lat)
+
+                time = c / option.speed; //总角度除以速度  
+                if (option.time)
+                    time = Math.min(option.time, time);
+            } else if (option.time)
+                time = option.time;
+
+            option.fuc && setTimeout(option.fuc, time)
+            //匀速:
+            option.constantSpeed && (speedFuc = null);
+
+
+        }
+        if (useLonLat) {
+            if (option.lon)
+                transitions.start(lerp.property(this, "lon", option.lon), time, null, 0, speedFuc);
+            if (option.lat)
+                transitions.start(lerp.property(this, "lat", option.lat), time, null, 0, speedFuc);
+        } else {
+            transitions.start(lerp.property(this, "lon", lon), time, null, 0, speedFuc);
+            transitions.start(lerp.property(this, "lat", lat), time, null, 0, speedFuc);
+        }
+    }
+
+    /**
+     * 记录拖拽旋转开始时的一些状态
+     * @param {number} clientX 屏幕坐标
+     * @param {number} clientY 屏幕坐标
+     */
+    startRotationFrom(clientX, clientY) {
+        //以屏幕中心为原点,得到pointer在屏幕的百分比
+        var mouse = math.handelPadding(clientX, clientY, this.dom);
+        math.convertScreenPositionToNDC(mouse.x, mouse.y, this.pointer, this.dom);
+        this.pointerDragOn = !0;
+        this.pointerDragStart.copy(this.pointer);
+        this.moveStart.copy(this.pointer);
+        this.rotationHistory = [];
+        this.rotationSpeed.set(0, 0);
+    }
+
+    onMouseOver(mouseEvent) {
+        !this.pointerDragOn || 0 !== mouseEvent.which && 0 !== mouseEvent.buttons || this.onMouseUp(mouseEvent)
+    }
+
+    onTouchStart(pointerEvent) {
+        if (this.usable()) {
+            pointerEvent.preventDefault();
+            pointerEvent.stopPropagation();
+            switch (pointerEvent.touches.length) {
+                case 1:
+                    this.startRotationFrom(pointerEvent.touches[0].clientX, pointerEvent.touches[0].clientY);
+                    break;
+                case 2:
+                    var t = (pointerEvent.touches[0].clientX - pointerEvent.touches[1].clientX) / app.player.domElement.clientWidth,
+                        i = (pointerEvent.touches[0].clientY - pointerEvent.touches[1].clientY) / app.player.domElement.clientHeight;
+                    this.pinchDistance = Math.sqrt(t * t + i * i);
+            }
+            this.emit(ControlEvents.InputStart, "touch");
+        }
+    }
+
+    onPointerDown(pointerEvent) {
+        if (this.usable() && "touch" === pointerEvent.pointerType)
+        {
+            if (this.pointers.length < this.pointersLimit)
+            {
+                this.pointers.push({
+                    id: pointerEvent.pointerId,
+                    clientX: pointerEvent.clientX,
+                    clientY: pointerEvent.clientY
+                });
+            }
+            pointerEvent.touches = this.pointers;
+            this.onTouchStart(pointerEvent);
+            this.emit(ControlEvents.InputStart, "pointer");
+        }
+    }
+
+    onMouseDown(mouseEvent) {
+        if (this.usable()) {
+            mouseEvent.preventDefault();
+            mouseEvent.stopPropagation();
+            switch (mouseEvent.button) {
+                case MouseButton.LEFT:
+                    this.startRotationFrom(mouseEvent.clientX, mouseEvent.clientY)
+            }
+            this.emit(ControlEvents.InputStart, "mouse")
+        }
+    }
+
+    /**
+     * 根据两帧交互点坐标之间的差值,计算两帧角度差值(rotationDifference)用于旋转
+     * 1.将两次交互点坐标分别映射到3D空间
+     * 2.通过两坐标在XY平面上投影,分别计算与X轴夹角,再求差值作为竖直方向角度差值(rotationDifference.y)
+     * 3.通过两坐标在XZ平面上投影,分别计算与X轴夹角,再求差值作为水平方向角度差值(rotationDifference.x)
+     */
+    updateRotation() {//算拖拽过的角度
+        if (this.usable() && this.pointerDragOn) {
+            this.camera.matrixWorld = new THREE.Matrix4(); //许钟文加  player的cameras里的panorama是不更新matrixworld的,只有player的camera才更新。不明白为什么更新了转动会很慢。为了miniView的相机旋转加这句。
+            //两交互点在3D空间的坐标
+            var pointerDragStart3D = new THREE.Vector3(this.pointerDragStart.x, this.pointerDragStart.y, -1).unproject(this.camera),
+                pointer3D = new THREE.Vector3(this.pointer.x, this.pointer.y, -1).unproject(this.camera)
+
+                //两交互点分别到原点的长度
+                ,
+                pointerDragStart3DLength = Math.sqrt(pointerDragStart3D.x * pointerDragStart3D.x + pointerDragStart3D.z * pointerDragStart3D.z),
+                pointer3DLength = Math.sqrt(pointer3D.x * pointer3D.x + pointer3D.z * pointer3D.z)
+
+                //通过Math.atan2计算分别与X轴的夹角弧度。
+                //注:因为 z = -1,所以两者到原点的长度近似为x分量,此处只是注重方上,数值的大小没有绝对对应关系
+                ,
+                anglePointerDragStart3DToX = Math.atan2(pointerDragStart3D.y, pointerDragStart3DLength) //近似为 anglePointerDragStart3DToX = Math.atan2( pointerDragStart3D.y, pointerDragStart3D.x ) 
+                ,
+                anglePointer3DToX = Math.atan2(pointer3D.y, pointer3DLength); //近似为 anglePointer3DToX = Math.atan2( pointer3D.y, pointer3D.x )
+
+            this.camera.updateMatrix();
+            this.camera.updateMatrixWorld();
+
+            this.rotationDifference.y = THREE.Math.radToDeg(anglePointerDragStart3DToX - anglePointer3DToX);
+            pointerDragStart3D.y = 0;
+            pointer3D.y = 0;
+            var anglePointerDragStart3DToPointer3D = Math.acos(pointerDragStart3D.dot(pointer3D) / pointerDragStart3D.length() / pointer3D.length());
+            // isNaN(s) || (this.rotationDifference.x = THREE.Math.radToDeg(s),
+            // this.pointerDragStart.x < this.pointer.x && (this.rotationDifference.x *= -1)),
+            if (!isNaN(anglePointerDragStart3DToPointer3D))
+            {
+                this.rotationDifference.x = THREE.Math.radToDeg(anglePointerDragStart3DToPointer3D);
+                if (this.pointerDragStart.x < this.pointer.x)
+                {
+                    this.rotationDifference.x *= -1;
+                }
+
+            }
+            this.pointerDragStart.copy(this.pointer);
+        }
+    }
+
+    /**
+     * 处理鼠标移动事件
+     * 1.计算鼠标的NDC坐标
+     * 2.判断是否是拖拽来决定拖拽行为的执行
+     * 3.通过预定义的防误触偏差(moveTolerance),来防止一定的误触
+     */
+    onMouseMove(mouseEvent) {
+        if (this.usable())
+        {
+            //许钟文加handelPadding这一行。
+            var mouse = math.handelPadding(mouseEvent.clientX, mouseEvent.clientY, this.dom)
+            math.convertScreenPositionToNDC(mouse.x, mouse.y, this.pointer, this.dom);
+            if (this.pointerDragOn)
+            {
+                if (Math.abs(this.pointer.x - this.moveStart.x) > this.moveTolerance || Math.abs(this.pointer.y - this.moveStart.y) > this.moveTolerance)
+                {
+                    this.emit(ControlEvents.Move, "mouse");
+                }
+            }
+        }
+    }
+
+
+    /**
+     * 处理触摸移动事件
+     * 1.单点触控记录NDC坐标
+     * 2.双点触控记录两触摸点距离(映射到[0-1]范围)
+     */
+    onTouchMove(pointerEvent) {
+        if (this.usable())
+        {
+            this.emit(ControlEvents.Move, "touch");
+            switch (pointerEvent.touches.length) {
+                case 1:
+                    var mouse = math.handelPadding(pointerEvent.touches[0].clientX, pointerEvent.touches[0].clientY, this.dom);
+                    math.convertScreenPositionToNDC(mouse.x, mouse.y, this.pointer, this.dom);
+                    break;
+                case 2:
+                    var t = (pointerEvent.touches[0].clientX - pointerEvent.touches[1].clientX) / app.player.domElement.clientWidth,
+                        i = (pointerEvent.touches[0].clientY - pointerEvent.touches[1].clientY) / app.player.domElement.clientHeight,
+                        n = this.pinchDistance - Math.sqrt(t * t + i * i);
+                    if (Math.abs(n) > .01)
+                    {
+                        this.emit(ControlEvents.InteractionDirect);
+                        this.emit(ControlEvents.Pinch, n);
+                        this.pinchDistance -= n;
+                    }
+            }
+        }
+    }
+
+    onPointerMove(pointerEvent) {
+        if (this.usable() && "touch" === pointerEvent.pointerType)
+        {
+            this.pointers.forEach(function(t) {
+                if (pointerEvent.pointerId === t.id)
+                {
+                    t.clientX = pointerEvent.clientX;
+                    t.clientY = pointerEvent.clientY;
+                }
+            });
+            pointerEvent.touches = this.pointers;
+            this.onTouchMove(pointerEvent);
+        }
+    }
+
+    /**
+     * 旋转终止后的行为
+     * 1.通过已记录的一组帧旋转量(rotationDifference)求平均值作为停止后惯性速度参考值。
+     * 2.通过设置的rotationAfterMoveMultiplier(惯性速度决定因子,用于手动指定影响惯性速度大小),来计算最后的的惯性速度
+     */
+    endRotation() {
+        this.pointerDragOn = !1;
+        var e = common.averageVectors(this.rotationHistory); 
+        this.rotationSpeed.set(e.x * settings.rotationAfterMoveMultiplierX, e.y * settings.rotationAfterMoveMultiplierY)
+    }
+
+    /**
+     * 触摸结束触发endRotation行为
+     */
+    onTouchEnd(pointerEvent) {
+        if (this.usable())
+        {
+            pointerEvent.preventDefault();
+            pointerEvent.stopPropagation();
+            this.endRotation();
+        }
+    }
+
+    /**
+     * 鼠标抬起触发endRotation行为
+     */
+    onMouseUp(mouseEvent) {
+        if (this.usable())
+        {
+            mouseEvent.preventDefault();
+            mouseEvent.stopPropagation();
+            this.endRotation(); 
+        }
+    }
+
+    onPointerUp(pointerEvent) {
+        if (this.usable() && "touch" === pointerEvent.pointerType)
+        {
+            this.pointers.forEach(function(t, i) {
+                pointerEvent.pointerId === t.id && this.pointers.splice(i, 1)
+            }.bind(this));
+            pointerEvent.touches = this.pointers;
+            this.onTouchEnd(pointerEvent);
+        }
+    }
+
+    /**
+     * 主循环更新,主要通过物理上的刚体旋转行为(角位移,角速度,角加速度,摩擦等)计算得到新的相机视点target,主要是每帧瞬时的状态
+     * 
+     *  updateRotation()计算每帧对应的旋转量 rotationDifference
+     * 
+     * 角位移:rotationDifference与原本lon,lat (等价于phi,theta)累加,得到新的角位移 
+     * 角速度:(rotationDifference数组的平均值 * 速度因子rotationAccelerationInside + 角加速度) - 摩擦rotationFriction。
+     * 
+     * target坐标:新的角位移计算出新的球坐标,转换计算后的球坐标到笛卡尔坐标系
+     * 
+     * @param { number } deltaTime 帧间隔时间。 注:关于帧间隔时间,是个有关物理计算的很重要的值,用于保持物理量与绝对时间的对应而不受帧率的的干扰,下文计算角速度用到。更多请见 https://blog.csdn.net/ChinarCSDN/article/details/82914420
+     */
+    update(deltaTime) { 
+		//移动端是鱼眼模式,过渡的时候需要采用鱼眼的算法来计算
+    	
+        // if(!objects.play.ifPlay()){
+        //     //许钟文-add------某些时刻不旋转
+        //     if(settings.vrEnabled || !this.player.flying &&!this.player.flyRotate && this.player.mode == "panorama"){
+        //         //原地mousemove旋转时,只需要直接改camera的quarternion
+        //         return;
+        //     }
+        // }
+        //许钟文-add------某些时刻不旋转
+        //if(settings.vrEnabled && !window.ifTest || !this.player.flying &&!this.player.flyRotate && this.player.mode == "panorama"&&!objects.play.control.onUpdate){
+            if((settings.vrEnabled && !window.ifTest) || !this.player.flying &&!this.player.flyRotate && this.player.mode == "panorama"&&!objects.play.control.onUpdate){
+            //原地mousemove旋转时,只需要直接改camera的quarternion
+            //logger.info('不执行PanoramaControls的update');
+            return;
+        }
+
+        
+        // 求出新的rotationDifference 
+        this.updateRotation();
+
+        //记录一组rotationDifference 用于求角速度 rotationSpeed。注:见 endRotation()
+        for (this.rotationHistory.push(this.rotationDifference.clone()); this.rotationHistory.length > settings.rotationAfterMoveHistoryCount;)
+        {
+            this.rotationHistory.shift();
+        }
+
+        //计算角位移(交互影响下的)
+        this.lon += this.rotationDifference.x;
+        this.lat += this.rotationDifference.y;
+        this.rotationDifference.set(0, 0);
+        //计算角速度
+		var friction = Math.min(1, settings.rotationFriction * deltaTime * 60) //如果deltaTime > 1/ 60 (比较卡),就增加rotationFriction, 以防止转动过久  
+        this.rotationSpeed.x = this.rotationSpeed.x * (1 - friction) + this.rotationAcc.x * settings.rotationAccelerationInside;
+        this.rotationSpeed.y = this.rotationSpeed.y * (1 - friction) + this.rotationAcc.y * settings.rotationAccelerationInside;
+        //计算角位移(交互后,物理定律影响下的)
+        this.lon += this.rotationSpeed.x * deltaTime;
+        this.lat += this.rotationSpeed.y * deltaTime;
+		
+		//许钟文 
+		if(this.limitDownAngel == null){//许钟文    在手机编辑墙壁时俯视角度可以增大
+			this.lat = Math.max(this.insideLookLimitDown!=null ? this.insideLookLimitDown : settings.insideLookLimitDown, Math.min(settings.insideLookLimitUp, this.lat)); //通过预定义的俯仰角最大最小范围(insideLookLimitUp、insideLookLimitDown)来限制俯仰角。 注:这种数学计算很常见,因此API也很常见(clamp),等价于 this.lat = THREE.Math.clamp( this.lat, settings.insideLookLimitDown, settings.insideLookLimitUp );   
+		}
+		else{
+			this.lat = this.limitDownAngel;//固定垂直视角
+		}
+		//转换为标准球坐标参数形式,并最终转换为笛卡尔坐标系下
+		this.phi = THREE.Math.degToRad(90 - this.lat);
+		this.theta = THREE.Math.degToRad(this.lon);
+		this.lookVector.x = Math.sin(this.phi) * Math.cos(this.theta);
+		this.lookVector.y = Math.cos(this.phi);
+		this.lookVector.z = Math.sin(this.phi) * Math.sin(this.theta);
+
+		//求taget坐标: 当前相机位置 + 方向向量(对于此处旋转来说距离并无意义,方向向量的1即可) 
+		this.target.copy(this.lookVector).add(this.camera.position);
+
+		//THREE的API来更新相机旋转。注:lookAt是四阶矩阵比较常见的API,因此此PanoramaControls计算流程,不算与THREE耦合
+        this.camera.lookAt(this.target);
+    }
+
+    //许钟文 加 用于鱼眼过渡
+    updateByLookVectorFish(onlyGetVector) {
+        var lookVector;
+        //前面几个条件的意思就是:只要不是简单不旋转的那种flying,就需要计算这些:
+        if (!this.player.flying || this.player.flyingToTag ||
+            this.player.flyRotate || this.player.flyingWithRot ||
+            this.player.isWarping() || onlyGetVector) { //减少计算
+
+            //if(!(this.player.flying && !this.player.flyingToTag && !player.isWarping() ) || onlyGetVector){//减少计算
+            this.lat = Math.max(settings.insideLookLimitDown, Math.min(settings.insideLookLimitUp, this.lat)),
+                this.phi = THREE.Math.degToRad(90 - this.lat),
+                this.theta = THREE.Math.degToRad(this.lon)
+            //FishCam_BackDist: 4/11
+            lookVector = new THREE.Vector3;
+            var backDist = settings.FishCam_BackDist;
+            lookVector.x = settings.skyRadius * backDist * Math.sin(this.phi) * Math.cos(this.theta); //改
+            lookVector.y = settings.skyRadius * backDist * Math.cos(this.phi);
+            lookVector.z = settings.skyRadius * backDist * Math.sin(this.phi) * Math.sin(this.theta); //改
+            this.fishState && this.camera.position.copy(lookVector).negate().add(this.target);
+        }
+        if (!onlyGetVector && !this.fishState) {
+            lookVector && this.lookVector.copy(lookVector)
+            this.target = this.player.currentTarget.clone();
+            this.camera.position.copy(this.lookVector).negate().add(this.target);
+            this.camera.lookAt(this.target);
+        } else {
+            return lookVector;
+        }
+    }
+
+    /**
+     * 滚轮行为: 触发自定义事件
+     */
+    onMouseWheel(wheelEvent) {
+        if (this.usable()) {
+            var t = wheelEvent.wheelDelta || -wheelEvent.detail;
+            this.emit(ControlEvents.InteractionDirect);
+            this.emit(ControlEvents.Scroll, t);
+        }
+    }
+
+    /**
+     * 键盘按下:触发自定义事件
+     */
+    onKeyDown(keyboardEvent) {
+        if (this.usable())
+        {
+            if (keyboardEvent.metaKey || keyboardEvent.ctrlKey) {}
+            else {
+
+                if (config.isTyping || config.isDisableControl) {
+                    return
+                }
+
+                keyboardEvent.preventDefault();
+                this.handleKeyDown(keyboardEvent.which);
+            }
+        }
+    }
+
+    handleKeyDown(keyValue) {
+        var t = function(e, t) {
+                this.rotationAcc[e] = t
+            }
+            .bind(this);
+        this.emit(ControlEvents.InteractionKey);
+        var i = !0;
+        switch (keyValue) {
+            case Keys.LEFTARROW:
+            case Keys.J:
+                t("x", -1);
+                break;
+            case Keys.RIGHTARROW:
+            case Keys.L:
+                t("x", 1);
+                break;
+            case Keys.I:
+                t("y", 1);
+                break;
+            case Keys.K:
+                t("y", -1);
+                break;
+            default:
+                i = !1
+        }
+        i && this.emit(ControlEvents.Move, "key")
+    }
+
+    onKeyUp(keyboardEvent) {
+        if (this.usable())
+        {
+            keyboardEvent.preventDefault();
+            keyboardEvent.stopPropagation();
+            this.handleKeyUp(keyboardEvent.which);
+        }
+    }
+
+    handleKeyUp(keyValue) {
+        switch (keyValue) {
+            case Keys.LEFTARROW:
+            case Keys.J:
+            case Keys.RIGHTARROW:
+            case Keys.L:
+                this.rotationAcc.x = 0;
+                break;
+            case Keys.I:
+            case Keys.K:
+                this.rotationAcc.y = 0
+        }
+    }
+
+    startRotating(e, t) {
+        e && (this.rotationAcc.x = e);
+        t && (this.rotationAcc.y = t);
+    }
+
+    /**
+     * 通过物理定律来终止旋转
+     */
+    stopRotating(e) {
+        e && (this.rotationSpeed.x = this.rotationSpeed.y = 0);
+        this.rotationAcc.set(0, 0);
+    }
+
+    reset() {
+        this.pointerDragOn = !1;
+        this.rotationAcc.set(0, 0);
+        this.rotationSpeed.set(0, 0);
+        this.pointers = [];
+    }
+
+    /**
+     * 序列化,用于保存状态。
+     */
+    toJSON() {
+        var cameraSpatialInfo = {
+            camera_position: {
+                x: math.toPrecision(this.camera.position.x, 4),
+                y: math.toPrecision(this.camera.position.y, 4),
+                z: math.toPrecision(this.camera.position.z, 4)
+            },
+            camera_quaternion: {
+                x: math.toPrecision(this.camera.quaternion.x, 4),
+                y: math.toPrecision(this.camera.quaternion.y, 4),
+                z: math.toPrecision(this.camera.quaternion.z, 4),
+                w: math.toPrecision(this.camera.quaternion.w, 4)
+            }
+        };
+        return cameraSpatialInfo;
+    }
+
+    /**
+     * 反序列化,用于读取状态
+     */
+    setStateFromJSON(cameraSpatialInfo) {
+        this.camera.position.copy(cameraSpatialInfo.camera_position);
+        this.camera.quaternion.copy(cameraSpatialInfo.camera_quaternion);
+    }
+}

+ 107 - 0
src/navigation/Reticule.js

@@ -0,0 +1,107 @@
+import * as THREE from "../../libs/three.js/build/three.module.js";
+import {MOUSE} 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'  */)  
+        var crosshairTex = texLoader.load(Potree.resourcePath+'/textures/reticule_cross_hair.png') 
+        
+        super(new THREE.PlaneBufferGeometry(0.15,0.15,1,1),new THREE.MeshBasicMaterial({
+            side: THREE.DoubleSide , 
+            map: defaultTex,
+            transparent:true,
+            depthTest: !1,
+            opacity: defaultOpacity,
+            //depthWrite: !1,
+        })) 
+        
+        //this.layers.set(0/* RenderLayers.RETICULE */);
+        this.renderOrder = 0
+        this.layers.set(Potree.config.renderLayers.marker);
+        
+        
+        this.direction = new THREE.Vector3;
+        this.hidden = !0;
+        this.mouseLastMoveTime = Date.now();
+
+
+        //viewer.inputHandler.addInputListener(this);
+        viewer.addEventListener('global_mousemove',this.move.bind(this))
+        
+        viewer.addEventListener('measureMovePoint',()=>{
+            this.material.map = crosshairTex
+            this.state = 'crosshair' 
+        }) 
+        viewer.addEventListener('endMeasureMove',()=>{
+            this.material.map = defaultTex 
+            this.state = 'default' 
+        }) 
+        this.state = 'default'
+        
+        viewer.setObjectLayers(this, 'reticule' )
+    }
+
+    move(e){
+        if(e.buttons == MOUSE.NONE || this.state == 'crosshair' ){//按下时不更新,除非拖拽测量
+            this.hidden = false,
+            this.mouseLastMoveTime = Date.now()
+            
+            this.updatePosition(e.intersectPoint, e.hoverViewport)
+        }
+    }
+
+    hide(){
+        //console.log("hide Reticule")
+        this.hidden || (this.hidden = !0,
+        transitions.start(lerp.property(this.material , "opacity", 0), 500))
+    }
+
+    show(){
+        if(!this.visible)return
+        //console.log("show Reticule")
+        this.hidden = !1,
+        this.material.opacity <= 0 && transitions.start(lerp.property(this.material, "opacity", defaultOpacity), 300)
+    }
+
+    //鼠标静止一段时间它就会消失
+    updateVisible(){
+        Date.now() - this.mouseLastMoveTime > 1500 && !this.hidden && this.hide()
+    }
+
+    updatePosition(intersectPoint, viewport ){ //在地图(当地图融合到viewer时)和场景里都显示且完全相同(大小可能不同)
+        if (!this.hidden && this.visible) {
+            if (!intersectPoint /* || !intersectPoint.point.normal */)
+                return //this.hide();
+            var atMap = !intersectPoint.location
+            let normal = intersectPoint.point ? new THREE.Vector3().fromArray(intersectPoint.point.normal ) : new THREE.Vector3(0,0,1)//地图无normal
+            let s, camera
+            let location = intersectPoint.location || intersectPoint.orthoIntersect.clone()
+                
+            if(!atMap){
+                camera = viewport.camera
+                let n = camera.position.distanceTo(location)
+                s = 1 + .01 * n;
+                n < 1 && (s -= 1 - n)
+            }else{
+                camera = viewer.mapViewer.camera
+                s = math.getScaleForConstantSize({width2d:300, position:location, camera, resolution:viewport.resolution2} )
+                location.setZ(0);//低于相机高度即可
+            }
+            
+            
+            
+            this.show();
+            this.scale.set(s, s, s);
+            this.direction = this.direction.multiplyScalar(.8); 
+            this.direction.add(normal.clone().multiplyScalar(.2));
+            this.position.copy(location).add(normal.clone().multiplyScalar(.01));
+            this.lookAt(this.position.clone().add(this.direction));
+        }
+    }
+}

+ 74 - 229
src/modules/route/RouteGuider.js

@@ -1,9 +1,10 @@
 
-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 * as THREE from "../../libs/three.js/build/three.module.js";
+import {Utils} from "../utils.js";
+import { EventDispatcher } from "../EventDispatcher.js";
+import Sprite from '../viewer/Sprite'
+
+
 const texLoader = new THREE.TextureLoader()
 const arrowSpacing = 1 //间隔
 const arrowSize = arrowSpacing * 0.5
@@ -12,63 +13,33 @@ 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 THREE.EventDispatcher{
+
+
+export class RouteGuider extends EventDispatcher{
     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)
+            if(camera.zoom != zoom){ 
+                this.updateMapArrows(true)
+                zoom = camera.zoom
+            } 
         })
         
-   
-        
-       
-        //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({ 
@@ -107,17 +78,17 @@ export class RouteGuider extends THREE.EventDispatcher{
             map
         }))
         this.arrow.scale.set(arrowSize,arrowSize,arrowSize)
-        viewer.setObjectLayers(this.arrow, 'sceneObjects' )
+        viewer.setObjectLayers(this.arrow, 'route' )
          
         
-        /* this.testArrow = this.arrow.clone();
+        this.testArrow = this.arrow.clone();
         this.testArrow.material = this.arrow.material.clone()
-        this.testArrow.material.color = 'red' */
+        this.testArrow.material.color = 'red'
         
         this.arrows = new THREE.Object3D;
         this.sceneMeshGroup.add(this.arrows)
         
-        viewer.setObjectLayers(this.sceneMeshGroup, 'sceneObjects' )
+        viewer.setObjectLayers(this.sceneMeshGroup, 'route' )
         //this.sceneMeshGroup.traverse(e=>e.renderOrder = 90)
         
         
@@ -135,65 +106,30 @@ export class RouteGuider extends THREE.EventDispatcher{
             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 = new THREE.Mesh( planeGeo, new THREE.MeshBasicMaterial({
+            transparent:true, depthTest:false,
+            map: texLoader.load(Potree.resourcePath+'/textures/routePoint_map_fsna.png' )  
+        }))
         this.mapArrow.scale.set(arrowSize,arrowSize,arrowSize)
         this.mapArrows = new THREE.Object3D;
         this.mapArrows.name = 'mapArrows'
-         
+        //viewer.setObjectLayers(this.mapArrow, 'route' )
+        
         
         
+        /* this.mapMeshGroup.add(this.mapMarkStart)
+        this.mapMeshGroup.add(this.mapMarkEnd) */
         this.mapMeshGroup.add(this.mapArrows)
         this.mapMeshGroup.name = 'mapRouteLayer'
         this.mapMeshGroup.visible = false
         
-        viewer.mapViewer.dispatchEvent({type:'add', object:this.mapMeshGroup, name:'route'})
+        viewer.mapViewer.emit('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
@@ -209,12 +145,10 @@ export class RouteGuider extends THREE.EventDispatcher{
             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)
@@ -241,7 +175,7 @@ export class RouteGuider extends THREE.EventDispatcher{
     setArrowDir(arrows,index){
         let arrow = arrows[index]
         var nextOne = arrows[index+1];
-        var nextPos = nextOne ? nextOne.position : this.endPolePos //routeEnd
+        var nextPos = nextOne ? nextOne.position : this.routeEnd
         var direction = new THREE.Vector3().subVectors(arrow.position, nextPos).setZ(0);
         //direction.normalize();
         //console.log(direction.toArray())
@@ -252,64 +186,37 @@ export class RouteGuider extends THREE.EventDispatcher{
     
     
      
-     
     
-    setRouteStart(pos, dealZ , datasetId  ){
+    
+    setRouteStart(pos, dealMapZ, ifReset){
         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)
+        this.routeStart = pos && new THREE.Vector3().copy(pos) 
+        //if(dealMapZ && this.routeStart) this.routeStart.setZ(0)//后端要求设置为0,但设置后反而得不到了。直接用的是接近boundingbox.min.z的值
+            console.log('setRouteStart',ifReset,this.routeStart&&this.routeStart.toArray()) 
+       
+        if(ifReset){
+            this.bus && this.bus.emit('reposStartMarker', pos)
+        }else{
+            this.generateRoute()
         }
-        console.log('setRouteStart',this.routeStart&&this.routeStart.toArray()) 
-        
-        this.datasetIds[0] = datasetId
-        
-        //this.setStartPole(pos)
-        
-        this.generateRoute()
-        
         
     }
     
-    setStartPole(pos){
-        this.startPolePos = pos
-        this.bus && this.bus.emit('reposStartMarker', pos)
-    }
-     
     
-    setRouteEnd(pos, dealZ , datasetId  ){ 
+    
+    setRouteEnd(pos, dealMapZ, ifReset){ 
         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的高度取的是主视图所在楼层的中心高度(可能再高些)
+        //if(dealMapZ && this.routeEnd) this.routeEnd.setZ(0)//后端要求设置为0
+            console.log('setRouteEnd',ifReset,this.routeEnd&&this.routeEnd.toArray())        
         
+        if(ifReset){
+            this.bus && this.bus.emit('reposEndMarker', pos)
+        }else{
+            this.generateRoute()
+        }
     }
     
-    setEndPole(pos){
-        this.endPolePos = pos
-        this.bus && this.bus.emit('reposEndMarker', pos)
-    }
     
     getSourceProjectionIndex(route) {//真正的起始
         var e = route.findIndex(function(t) {
@@ -326,7 +233,6 @@ export class RouteGuider extends THREE.EventDispatcher{
     
     generateRoute(){
         if(!this.routeStart || !this.routeEnd){ 
-            
             return
         }
         
@@ -354,7 +260,7 @@ export class RouteGuider extends THREE.EventDispatcher{
             this.updateMapArrows() 
             this.displayRoute()
             
-            {//map focus on this area
+            {
                 
                 const minBound = new THREE.Vector2(1,1)//针对垂直线,在地图上只有一个点
                 let bound = new THREE.Box2;
@@ -362,13 +268,7 @@ export class RouteGuider extends THREE.EventDispatcher{
                     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) ///边距 重点是起始和终点的标识占据较大
+                let margin = viewer.mapViewer.viewports[0].resolution2.clone().multiplyScalar(0.01)
                 size.add(margin)
                 let center = bound.getCenter(new THREE.Vector2)
                 
@@ -387,36 +287,19 @@ export class RouteGuider extends THREE.EventDispatcher{
         if(Potree.fileServer){
             let dealData = (data)=>{
                 
-                if(!data.data){
+                if(!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 )
+                    this.bus && this.bus.emit('gotResult','没有数据')
                     
                     return //this.generateDeferred && this.generateDeferred.resolve()
                 }
-                
-                
-                data = data.data 
+                 
                   
                 this.clearRoute()
                 let length = data.length
                 
-                if(length < 2){//可能距离太短 
-                    console.log('路径点数为'+length+',直接取起点和终点连线') 
+                if(length == 0){//可能距离太短
+                    console.log('路径点数为0,直接取起点和终点连线')
                     this.route = [this.routeStart, this.routeEnd];
                 }else{ 
                     let startIndex = this.getSourceProjectionIndex(data)
@@ -426,17 +309,15 @@ export class RouteGuider extends THREE.EventDispatcher{
                     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)
+                        pos = new THREE.Vector3().fromArray(pos)
                         this.route.push(pos)
                     })
                     
                     console.log(this.route)
                     
-                    
+                    this.setRouteStart(this.route[0],false, true) 
+                    this.setRouteEnd(this.route[this.route.length-1],false,true) 
                 }
-                this.setStartPole(this.route[0]) 
-                this.setEndPole(this.route[this.route.length-1]) 
-                
                 create()
                 /*
                     distance: 0.17581000000000116
@@ -453,20 +334,21 @@ export class RouteGuider extends THREE.EventDispatcher{
             
             
             
-            if(this.lastResult && (this.lastResult.data || this.lastResult.data.code != 4002)){//正被修改数据集的话要重新计算
-                let data = Common.CloneObject(this.lastResult.data) ,  use;  //直接用上次的结果
+            if(this.lastResult){
+                let data, use;  //直接用上次的结果
                 if(this.lastResult.routeStart.equals(this.routeStart) &&  this.lastResult.routeEnd.equals(this.routeEnd)){//和上次请求相同
-                    use = true 
+                    use = true
+                    data = this.lastResult.data
+                    
                 }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()
-                    }    
+                    data = this.lastResult.data.slice(0).reverse()
                 }
                 if(use){
                     console.log('直接用上次的结果')
                     return setTimeout(()=>{dealData(data)}, 1)//延迟是为了等待获得 RouteGuider.generateDeferred
-                       
+                     
+                    
                 }
                 
             }
@@ -487,10 +369,7 @@ export class RouteGuider extends THREE.EventDispatcher{
                 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}?`
+            let url = `/laser/route/${Potree.settings.number}/getRoute?`
             for(let i in query){
                 url+= (i + '='+ query[i] +'&')
             }
@@ -502,11 +381,10 @@ export class RouteGuider extends THREE.EventDispatcher{
                 this.lastResult = {//保存数据
                     routeStart : this.routeStart.clone(),
                     routeEnd: this.routeEnd.clone(),
-                    data,
-                     
+                    data : data.data
                 }
                 
-                dealData(data)
+                dealData(data.data)
                 
             })
             
@@ -536,9 +414,6 @@ export class RouteGuider extends THREE.EventDispatcher{
         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() 
@@ -549,62 +424,33 @@ export class RouteGuider extends THREE.EventDispatcher{
         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.poleStart.position.copy(this.routeStart)
+            this.poleEnd.position.copy(this.routeEnd)
             /* this.mapMarkStart.position.copy(this.routeStart).setZ(0)
             this.mapMarkEnd.position.copy(this.routeEnd).setZ(0) */
             this.scenePoints.forEach(e=>this.addArrow(e))
             this.arrows.children.forEach((e,i)=>this.setArrowDir(this.arrows.children,i));
         }
-        this.sceneMeshGroup.traverse(e=>e.visible = true)  
-        this.mapMeshGroup.visible = true
+        this.sceneMeshGroup.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={}){
@@ -624,9 +470,8 @@ export class RouteGuider extends THREE.EventDispatcher{
             this.mapArrows.remove(e)
         })
         
-        this.sceneMeshGroup.traverse(e=>e.visible = false)  //包括sprite也要设置,防止update
+        this.sceneMeshGroup.visible = false 
         this.mapMeshGroup.visible = false
-        viewer.mapViewer.dispatchEvent({'type':'content_changed'})
     }
     
     clear(){//退出

+ 5 - 4
src/navigation/VRControls.js

@@ -1,5 +1,6 @@
 
-import * as THREE from "../../libs/three.js/build/three.module.js"; 
+import * as THREE from "../../libs/three.js/build/three.module.js";
+import {EventDispatcher} from "../EventDispatcher.js";
 import { XRControllerModelFactory } from '../../libs/three.js/webxr/XRControllerModelFactory.js';
 import {Line2} from "../../libs/three.js/lines/Line2.js";
 import {LineGeometry} from "../../libs/three.js/lines/LineGeometry.js";
@@ -276,7 +277,7 @@ class RotScaleMode{
 };
 
 
-export class VRControls extends THREE.EventDispatcher{
+export class VRControls extends EventDispatcher{
 
 	constructor(viewer){
 		super(viewer);
@@ -335,7 +336,7 @@ export class VRControls extends THREE.EventDispatcher{
 
 				let lineMaterial = new LineMaterial({ 
 					color: 0xff0000, 
-					lineWidth: 2, 
+					linewidth: 2, 
 					resolution:  new THREE.Vector2(1000, 1000),
 				});
 
@@ -386,7 +387,7 @@ export class VRControls extends THREE.EventDispatcher{
 
 				let lineMaterial = new LineMaterial({ 
 					color: 0xff0000, 
-					lineWidth: 2, 
+					linewidth: 2, 
 					resolution:  new THREE.Vector2(1000, 1000),
 				});
 

+ 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 - 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 - 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 - 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 - 291
src/objects/tool/Compass.js

@@ -1,291 +0,0 @@
- 
-import * as THREE from "../../../libs/three.js/build/three.module.js";
-
-
-
-const initDir = new THREE.Vector3(0,1,0)//指南针模型的北方向 向屏幕里
-
-class Compass extends THREE.EventDispatcher{
-    
-    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)
-            this.renderer.setSize(width/2, height/2, false, 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 - 0
src/objects/tool/HandleSprite.js


Algúns arquivos non se mostraron porque demasiados arquivos cambiaron neste cambio