Pārlūkot izejas kodu

测量增加多段线。
测量在全景里允许加在深度图上,得到的点云算当前点位的。 depTexLocBindDataset
全景时有深度图的visibleNodes为空,优化流畅性

xzw 2 gadi atpakaļ
vecāks
revīzija
27c5aef1cf

+ 8 - 8
libs/other/BinaryHeap.js

@@ -10,29 +10,29 @@
 
 
 
-function BinaryHeap(scoreFunction){
+function BinaryHeap(scoreFunction){ //二叉堆(最小堆,根节点权重最大,子节点都比父节点小)
   this.content = [];
   this.scoreFunction = scoreFunction;
 }
 
 BinaryHeap.prototype = {
-  push: function(element) {
+  push: function(element) { //加入一个元素
     // Add the new element to the end of the array.
     this.content.push(element);
     // Allow it to bubble up.
-    this.bubbleUp(this.content.length - 1);
+    this.bubbleUp(this.content.length - 1); //重排序
   },
 
-  pop: function() {
+  pop: function() { //取出权重最大的一个
     // Store the first element so we can return it later.
     var result = this.content[0];
     // Get the element at the end of the array.
-    var end = this.content.pop();
+    var end = this.content.pop();       //取出底部最小的,让它像细砂一般从最上方下沉,直到能够接住它密度合适的区域为止
     // If there are any elements left, put the end element at the
     // start, and let it sink down.
     if (this.content.length > 0) {
       this.content[0] = end;
-      this.sinkDown(0);
+      this.sinkDown(0);         //重排序
     }
     return result;
   },
@@ -62,7 +62,7 @@ BinaryHeap.prototype = {
     return this.content.length;
   },
 
-  bubbleUp: function(n) {
+  bubbleUp: function(n) {//从位置n上浮,一般n为最末
     // Fetch the element that has to be moved.
     var element = this.content[n], score = this.scoreFunction(element);
     // When at 0, an element can not go up any further.
@@ -83,7 +83,7 @@ BinaryHeap.prototype = {
     }
   },
 
-  sinkDown: function(n) {
+  sinkDown: function(n) {//从位置n下沉(一般n为0)
     // Look up the target element and its score.
     var length = this.content.length,
     element = this.content[n],

+ 8 - 4
libs/three.js/lines/LineMaterial.js

@@ -35,6 +35,7 @@ UniformsLib.line = {
 	lineWidth: { value: 1 },
 	resolution: { value: new Vector2( 1, 1 ) },
     viewportOffset: { value: new Vector2(0, 0 ) }, //left, top    
+    devicePixelRatio:{ value:window.devicePixelRatio},
 	dashScale: { value: 1 },
 	dashSize: { value: 1 },
 	dashOffset: { value: 0 },
@@ -72,7 +73,9 @@ ShaderLib[ 'line' ] = {
 
 		uniform float lineWidth;
 		uniform vec2 resolution;
-
+        uniform float devicePixelRatio;  //add
+        
+        
 		attribute vec3 instanceStart;
 		attribute vec3 instanceEnd;
 
@@ -270,7 +273,7 @@ ShaderLib[ 'line' ] = {
 				offset *= lineWidth;
 
 				// adjust for clip-space to screen-space conversion // maybe resolution should be based on viewport ...
-				offset /= resolution.y;
+				offset /= resolution.y * devicePixelRatio;
 
 				// select end
 				vec4 clip = ( position.y < 0.5 ) ? clipStart : clipEnd;
@@ -491,7 +494,7 @@ ShaderLib[ 'line' ] = {
                 float clipFactor = 0.0;
 
                 float fragDepth = convertToLinear(gl_FragCoord.z);
-
+                //gl_FragCoord大小为 viewport client大小 
                 vec2 depthTxtCoords = vec2(gl_FragCoord.x - viewportOffset.x,  gl_FragCoord.y - viewportOffset.y) / resolution;
 
                 float textureDepth = convertToLinear(texture2D(depthTexture, depthTxtCoords).r);
@@ -885,8 +888,9 @@ class LineMaterial extends ShaderMaterial {
         let setSize = (e)=>{ 
             let viewport = e.viewport
             let viewportOffset = viewport.offset || new Vector2() 
-            this.uniforms.resolution.value.copy(viewport.resolution2) 
+            this.uniforms.resolution.value.copy(viewport.resolution) 
             this.uniforms.viewportOffset.value.copy(viewportOffset) 
+            this.uniforms.devicePixelRatio.value = window.devicePixelRatio
             this.lineWidth = this.lineWidth_
         }
         

+ 1 - 1
src/LRU.js

@@ -153,7 +153,7 @@ class LRU{
 
 			// console.log(current);
 
-			current.dispose();
+			current.dispose();      //真正删除geometry等
 			this.remove(current);
 
 			for (let key in current.children) {

+ 1 - 1
src/PointCloudOctree.js

@@ -105,7 +105,7 @@ export class PointCloudOctree extends PointCloudTree {//base
 	constructor (geometry, material) {
 		super();
 
-		this.pointBudget = Infinity;
+		this.pointBudget = Infinity; //一直是这个值
 		this.pcoGeometry = geometry;
 		this.boundingBox = this.pcoGeometry.boundingBox;
 		this.boundingSphere = this.boundingBox.getBoundingSphere(new THREE.Sphere());

+ 11 - 7
src/Potree.js

@@ -1,7 +1,7 @@
     
-  
-  export * from "./custom/start.js";
-  export {settings, config} from './custom/settings.js'  
+//export * from "./Potree_update_visibility.js";  //因加载顺序问题,该文件直接在shim中重写
+export * from "./custom/start.js";
+export {settings, config} from './custom/settings.js'  
    
 export * from "./Actions.js"; 
 export * from "./Annotation.js";
@@ -16,7 +16,7 @@ export * from "./ExtendPointCloudOctree.js";
 export * from "./PointCloudOctreeGeometry.js";
 export * from "./PointCloudTree.js";
 export * from "./Points.js";
- 
+
 export * from "./PotreeRenderer.js";
 export * from "./ProfileRequest.js";
 export * from "./custom/objects/TextSprite.js";
@@ -86,9 +86,11 @@ export * from "./modules/loader/2.0/OctreeLoader.js";
 
 export {OrbitControls} from "./navigation/OrbitControls.js";
 export {FirstPersonControls} from "./navigation/FirstPersonControls.js"; 
-	
-
-    
+	 
+     
+ 
+     
+     
 import "./extensions/OrthographicCamera.js";
 import "./extensions/PerspectiveCamera.js";
 import "./extensions/Ray.js";
@@ -508,3 +510,5 @@ export function loadPointCloud(path, name, sceneCode, timeStamp, callback, onErr
 		}
 	});
 })(jQuery);
+
+//在这之后export的内容才赋值到Potree中 

+ 3 - 12
src/PotreeRendererNew.js

@@ -1307,22 +1307,13 @@ export class Renderer {
 				shader.setUniform1i("clipTask", ClipTask.NONE);
 			}else{
 				shader.setUniform1i("clipTask", material.clipTask);
-			} 
-
+			}  
 			shader.setUniform1i("clipMethod", material.clipMethod);*/
-
+            //改
 			if (material.clipBoxes_in && material.clipBoxes_in.length > 0) {
-				//let flattenedMatrices = [].concat(...material.clipBoxes.map(c => c.inverse.elements));
-
-				//const lClipBoxes = shader.uniformLocations["clipBoxes[0]"];
-				//gl.uniformMatrix4fv(lClipBoxes, false, flattenedMatrices);
-
-				/* const lClipBoxes = shader.uniformLocations["clipBoxes[0]"];
-				gl.uniformMatrix4fv(lClipBoxes, false, material.uniforms.clipBoxes.value); */
-                //改
+				//let flattenedMatrices = [].concat(...material.clipBoxes.map(c => c.inverse.elements)); 
                 const lClipBoxes = shader.uniformLocations["clipBoxes_in[0]"];
 				gl.uniformMatrix4fv(lClipBoxes, false, material.uniforms.clipBoxes_in.value); 
-                
 			}
             
             if (material.clipBoxes_out && material.clipBoxes_out.length > 0) {//add

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

@@ -17,12 +17,14 @@ class BasicMaterial  extends THREE.ShaderMaterial{
             
     } 
      
-    clone(){
-        let prop = {opacity: this.opacity}
-        if(this.map) prop.map = this.map
-        return new BasicMaterial(prop)
-    }
     
+    copy(source){
+        super.copy(source)
+        
+        this.map = source.map
+         
+        return this
+    }
     
     set opacity(o){
         this.uniforms && (this.uniforms.opacity.value = o)

+ 75 - 62
src/custom/materials/DepthBasicMaterial.js

@@ -24,12 +24,7 @@ export default class DepthBasicMaterial extends THREE.ShaderMaterial{
       
 
 		}  
-        
-        let defines = {};
-        
-        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'],   
@@ -37,93 +32,87 @@ export default class DepthBasicMaterial extends THREE.ShaderMaterial{
             depthWrite: !1,
             depthTest: !1,
             transparent: o.transparent == void 0 ?  true : o.transparent,
-            side: o.side || 0 /* THREE.DoubleSide */,
-            defines, 
+            side: o.side || 0 /* THREE.DoubleSide */, 
         })
-        if(o.opacity != void 0){
-            this.opacity = o.opacity
-        }
-       
-        if(useDepth) this.useDepth_ = true
         
         
-      
-        
-        if(this.useDepth){  
         
-            let setSize = (e)=>{//如果出现横条状的异常,往往是viewportOffset出错 
+        this.events = {
+            setSize:(e)=>{//如果出现横条状的异常,往往是viewportOffset出错  //地图不需要
+                if(!this.useDepth || !e.viewport.camera.isPerspectiveCamera || !e.viewport)return
                 let viewport = e.viewport
                 let viewportOffset = viewport.offset || new THREE.Vector2() 
-                this.uniforms.resolution.value.copy(viewport.resolution2) 
+                this.uniforms.resolution.value.copy(viewport.resolution) 
                 this.uniforms.viewportOffset.value.copy(viewportOffset)
-                
-                //console.log('depth '+viewportOffset.toArray())
+            },
+            render:(e)=>{//before render  如果有大于两个viewport的话,不同viewport用不同的depthTex
+                this.updateDepthParams(e)
+            },
+            cameraChange:(e)=>{
+                if(e.changeInfo.projectionChanged){//resize时也会触发。虽然保守起见的话加上resize比较好
+                    //console.log('projectionChanged')
+                    this.events.setSize(e)
+                }
             }
             
-            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)
-            })
-            
-            this.updateDepthParams()
-        }
+        
+        //-----其他----
          
         
-        //点云变化时要一直触发updateDepthParams??
-        //viewer.once("render.pass.end",this.updateDepthParams.bind(this))
+        if(o.opacity != void 0){
+            this.opacity = o.opacity
+        }
+        this.useDepth = o.useDepth
+        this.map = o.map
+       
+   
     }
     
-    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   //其实只赋值一次就行
-            //}
-            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 的话会失效
         if(this.useDepth_ != value){
             if(value && Features.EXT_DEPTH.isSupported()){
-                this.defines.useDepth = ''
-                this.updateDepthParams()
+                this.defines.useDepth = '' 
+                //viewer.addEventListener('resize', this.events.setSize)
+                viewer.addEventListener("render.begin",  this.events.render) 
+                viewer.addEventListener('camera_changed', this.events.cameraChange)      
+                this.events.setSize( {viewport:viewer.mainViewport} )
+                this.updateDepthParams() 
+                
             }else{
                 delete this.defines.useDepth
+                //viewer.removeEventListener('resize', this.events.setSize)
+                viewer.removeEventListener("render.begin",  this.events.render)  
+                viewer.removeEventListener('camera_changed', this.events.cameraChange) 
             }
             this.useDepth_ = value
             this.needsUpdate = true
         }
     } 
     
-    
+     
+    get map(){
+        return this.uniforms.map.value
+    }
+    set map(map){
+        this.uniforms.map.value = map; 
+        if(map){
+            this.defines.use_map = '' 
+        }else{
+            delete this.defines.use_map 
+        }
+    }
+     
     get opacity(){
         return this.uniforms.opacity.value
     }
@@ -144,4 +133,28 @@ export default class DepthBasicMaterial extends THREE.ShaderMaterial{
         viewer.depthBasic
     } */
     
+    copy(source){
+        super.copy(source)
+        
+        this.useDepth = source.useDepth
+        this.map = source.map  
+        return this
+    }
+    
+    updateDepthParams(e={}){//主要用于点云遮住mesh
+        var viewport = e.viewport || viewer.mainViewport;
+        var camera = viewport.camera;
+        if(this.useDepth && camera.isPerspectiveCamera ){   
+            /* 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   //其实只赋值一次就行
+            //}
+            this.uniforms.nearPlane.value = camera.near;
+            this.uniforms.farPlane.value = camera.far;
+            
+        }            
+    }
+
+    
 }

+ 5 - 6
src/custom/modules/datasetAlignment/Alignment.js

@@ -67,7 +67,7 @@ var Alignment = {
             }
             
                              
-            this.history.beforeChange(e.pointclouds, e.pointclouds, [Potree.ExtendPointCloudOctree])    
+            this.history.beforeChange(e.pointclouds)    
             //this.writeToHistory( e.pointclouds ) 
               
             if(!transfromInfo){  
@@ -149,18 +149,17 @@ var Alignment = {
         })
         
         
-        viewer.fpControls.addEventListener("end",(e)=>{  
-            //this.prepareRecord = true
-            transfromInfo && this.history.afterChange(transfromInfo.pointclouds , transfromInfo.pointclouds )
+        viewer.fpControls.addEventListener("end",(e)=>{   
+            transfromInfo && this.history.afterChange(transfromInfo.pointclouds )
             transfromInfo = null 
         })
         
         viewer.inputHandler.addEventListener('keydown',e=>{ 
-            /* if(e.keyCode == 90 && e.event.ctrlKey){//Z
+            if(e.keyCode == 90 && e.event.ctrlKey){//Z
                 this.history.undo()
             }else if(e.keyCode == 89 && e.event.ctrlKey){//Y
                 this.history.redo()
-            } */
+            }
         })  
 		 
         

+ 25 - 8
src/custom/modules/panoEdit/panoEditor.js

@@ -10,6 +10,7 @@ import Sprite from "../../objects/Sprite.js";
 import {transitions, easing, lerp} from '../../utils/transitions.js'
 import {TransformControls} from "../../objects/tool/TransformControls.js";
 import SplitScreen from "../../utils/SplitScreen.js"
+import DepthBasicMaterial from "../../materials/DepthBasicMaterial.js";
 
 
 
@@ -896,32 +897,48 @@ class PanoEditor extends THREE.EventDispatcher{
     
     addPanoMesh(){ 
         let map = texLoader.load(Potree.resourcePath+'/textures/correct_n.png' )  
-        circleMats.default_normal = new THREE.MeshBasicMaterial({
+        /* circleMats.default_normal = new THREE.MeshBasicMaterial({
             map,
             color: 0xffffff,
             transparent: true,
             depthTest: false,
             depthWrite: false,  
-        })
+        }) */
+        window.circleMats = circleMats
+        circleMats.default_normal = new DepthBasicMaterial({
+            map,
+            color: 0xffffff,
+            transparent: true,
+            /* depthTest: false,
+            depthWrite: false, */ 
+            clipDistance : 5,//消失距离
+            occlusionDistance: 2,//变为backColor距离   
+            useDepth:true,
+            maxClipFactor: 0.6,
+            backColor: 0x33ffdd,
+        }) 
+        
         circleMats.default_rtk_on = circleMats.default_normal.clone();
         circleMats.default_rtk_on.map = texLoader.load(Potree.resourcePath+'/textures/rtk-y-n.png' )  
         circleMats.default_rtk_off = circleMats.default_normal.clone();
         circleMats.default_rtk_off.map = texLoader.load(Potree.resourcePath+'/textures/rtk-f-n.png' )  
         circleMats.selected_normal = circleMats.default_normal.clone();
         circleMats.selected_normal.map = texLoader.load(Potree.resourcePath+'/textures/correct_s.png' ) 
-        circleMats.selected_rtk_on = circleMats.default_normal.clone();
+        circleMats.selected_normal.useDepth = false;
+        circleMats.selected_rtk_on = circleMats.selected_normal.clone();
         circleMats.selected_rtk_on.map = texLoader.load(Potree.resourcePath+'/textures/rtk-y-s.png' ) 
-        circleMats.selected_rtk_off = circleMats.default_normal.clone();
+        circleMats.selected_rtk_off = circleMats.selected_normal.clone();
         circleMats.selected_rtk_off.map = texLoader.load(Potree.resourcePath+'/textures/rtk-f-s.png' ) 
         
         circleMats.hovered_normal = circleMats.default_normal.clone();
         circleMats.hovered_normal.color.set(0x00ff00)
+        circleMats.hovered_normal.useDepth = false
         circleMats.hovered_rtk_on = circleMats.default_rtk_on.clone();
-        circleMats.hovered_rtk_on.color.set(0x00ff00) 
+        circleMats.hovered_rtk_on.color.set(0x00ff00)
+        circleMats.hovered_rtk_on.useDepth = false        
         circleMats.hovered_rtk_off = circleMats.default_rtk_off.clone();
         circleMats.hovered_rtk_off.color.set(0x00ff00)
-        
-         
+        circleMats.hovered_rtk_off.useDepth = false         
         
         
         
@@ -948,7 +965,7 @@ class PanoEditor extends THREE.EventDispatcher{
                 renderOrder : renderOrders.circle,
                 pickOrder: renderOrders.circle
             })    
-            
+            circle.pickDontCheckDis = true
             circle.name = 'panoCircle'
             circle.sid = pano.id
             circle.pano = pano;

+ 9 - 0
src/custom/objects/Magnifier.js

@@ -39,8 +39,14 @@ export default class Magnifier extends THREE.Object3D {//放大镜or望远镜
             let sizeType
             let colorType
             let opacityBefore = new Map()
+            let visiMap = new Map()
             this.viewport.beforeRender = ()=>{
+                
+                
                 viewer.scene.pointclouds.forEach(e=>{//因为更改pointDensity时会自动变opacity,所以这项最先获取
+                    visiMap.set(e,e.visible)
+                    e.visible = viewer.getObjVisiByReason(e, 'datasetSelection'); //先将隐藏的点云显示
+                
                     opacityBefore.set(e,e.temp.pointOpacity)  
                 }) 
                 
@@ -66,10 +72,13 @@ export default class Magnifier extends THREE.Object3D {//放大镜or望远镜
                 Potree.settings.pointDensity = density
                 
                 viewer.scene.pointclouds.forEach(e=>{
+                    
+                    e.visible = visiMap.get(e)                      
                     e.material.pointSizeType = sizeType
                     e.material.activeAttributeName = colorType  
                     e.changePointOpacity(opacityBefore.get(e))  
                 }) 
+                
             } 
         }
         

+ 6 - 3
src/custom/objects/tool/Measure.js

@@ -81,17 +81,17 @@ export class Measure extends ctrlPolygon{
         this.area = {value:0,string:''}
          
         
-        if(this.closed/* this.showArea */){
+        if(/* this.closed */  this.showArea  ){
             this.areaLabel = this.createAreaLabel(); 
             this.add(this.areaLabel) 
         }
         
 		 
         //add:
-        if(this.maxMarkers > 2 || this.faceDirection){
+        if(this.showArea || this.faceDirection){ //是一个平面上的话
             this.createGuideLine(); 
         }
-        if(this.measureType == 'Distance'){
+        if(this.measureType == 'Distance' /* || this.measureType.includes('MulDistance') */){
             this.createHorVerGuideLine()
         }
         
@@ -806,6 +806,9 @@ export class Measure extends ctrlPolygon{
 
     
     
+    //closed的不一定在同一个平面上,但一般是
+    //showArea 能表示closed且在同一个平面上。虽然按道理反过来并不成立,但在此约定所有在同一平面的closed的都显示面积。
+      
     transformData(prop){
         if(prop.measureType == 'Point'){ 
             prop.showCoordinates = true, 

+ 5 - 8
src/custom/objects/tool/ctrlPolygon.js

@@ -23,7 +23,7 @@ export class ctrlPolygon extends THREE.Object3D {
             this[i] = prop[i]
         }
         
-        if(this.closed && this.dimension == '2d'){
+        if(this.showArea && this.dimension == '2d'){
             this.areaPlane = this.createAreaPlane(); 
             this.add(this.areaPlane)
         }
@@ -184,10 +184,7 @@ export class ctrlPolygon extends THREE.Object3D {
             if (i !== -1) {  
                 this.dragChange(I.clone(), i, atMap) 
                 
-                /* if(this.points_datasets){
-                    if(e.intersect.pointcloud) this.points_datasets[i] = e.intersect.pointcloud.dataset_id
-                    else this.points_datasets[i] = null
-                } */ 
+               
                 if(this.points_datasets){
                     if(e.intersect.pointcloud) this.points_datasets[i] = e.intersect.pointcloud.dataset_id
                     else if(e.intersect.object) this.points_datasets[i] = e.intersect.object.dataset_id
@@ -288,7 +285,7 @@ export class ctrlPolygon extends THREE.Object3D {
 
             if(len > 2){ 
                 
-                if(!this.faceDirection && this.closed){ 
+                if(!this.faceDirection && this.showArea){ 
                     if(len == 3 || this.isRect) this.cannotConfirmNormal = true //当第三个点固定后(有四个点时)才能固定面
                     if(!this.facePlane || this.cannotConfirmNormal){
                         var points3 = getDifferentPoint(points, 3);//只有找到三个不同的点算拥有面和area
@@ -344,7 +341,7 @@ export class ctrlPolygon extends THREE.Object3D {
                 } */
                 this.getPoint2dInfo(points)
                 
-                var isIntersectSelf = this.closed && !this.isRect && len > 3 && this.intersectSelf(this.point2dInfo.points2d)//检测相交
+                var isIntersectSelf = this.showArea && !this.isRect && len > 3 && this.intersectSelf(this.point2dInfo.points2d)//检测相交
                 if(isIntersectSelf){
                     //not-allowed
                     viewer.dispatchEvent({
@@ -467,7 +464,7 @@ export class ctrlPolygon extends THREE.Object3D {
     };
     
     getFacePlane(){//最普通一种get方法,根据顶点。且假设所有点已经共面,且不重合
-        if(this.points.length<3) return
+        if(!this.showArea || this.points.length<3) return
         this.facePlane = new THREE.Plane().setFromCoplanarPoints(...this.points.slice(0,3) )
          
     }

+ 59 - 96
src/custom/potree.shim.js

@@ -3,8 +3,8 @@
 // }
 import * as THREE from "../../libs/three.js/build/three.module.js";
 import math from "./utils/math.js";
-import browser from "./utils/browser.js";
- 
+import browser from "./utils/browser.js"; 
+import cameraLight from "./utils/cameraLight.js";
 import {Utils} from "../utils.js";
 import {BinaryLoader} from "../loader/BinaryLoader.js";
 import {Features} from "../Features.js";
@@ -28,6 +28,11 @@ import {LineSegmentsGeometry} from '../../libs/three.js/lines/LineSegmentsGeomet
 import {LineGeometry} from '../../libs/three.js/lines/LineGeometry.js'  
 KeyCodes.BACKSPACE = 8
 
+
+//注意,这时候Potree.js中export的内容还不在Potree变量中
+
+
+
 {//defines:
     Potree.defines = {}
     Potree.defines.Buttons = {// MouseEvent.buttons
@@ -210,7 +215,7 @@ Utils.loadSkybox = function(path) {
 
 Utils.getMousePointCloudIntersection = function(viewport, mouse, pointer, camera, viewer, pointclouds, pickParams = {} ) {
     if(!pointclouds || pointclouds.length == 0)return
-    
+    //console.log('getMousePointCloudIntersection')
     let renderer = viewer.renderer;
     
       
@@ -253,6 +258,7 @@ Utils.getMousePointCloudIntersection = function(viewport, mouse, pointer, camera
     let density
     let sizeType
     let size = new Map()  
+    let visiMap = new Map()
     let needsUpdate = false;
     
     if(pickParams.isMeasuring || Potree.settings.displayMode == 'showPanos'){ //测量或全景模式提高精准度
@@ -260,6 +266,9 @@ Utils.getMousePointCloudIntersection = function(viewport, mouse, pointer, camera
         Potree.settings.pointDensity = 'magnifier' 
         
         pointclouds.forEach(e=>{//因为全景模式的pointSizeType是fixed所以要还原下
+            visiMap.set(e,e.visible)
+            e.visible = viewer.getObjVisiByReason(e, 'datasetSelection'); //先将隐藏的点云显示
+            if(!e.visible)return
             size.set(e, e.temp.pointSize)    
             sizeType = e.material.pointSizeType  
             e.material.pointSizeType = Potree.config.material.pointSizeType 
@@ -314,14 +323,16 @@ Utils.getMousePointCloudIntersection = function(viewport, mouse, pointer, camera
         }
     }
 
-
+    //恢复
     if(pickParams.isMeasuring || Potree.settings.displayMode == 'showPanos'){
         Potree.settings.pointDensity = density
         
         pointclouds.forEach(e=>{
-            e.material.pointSizeType = sizeType
-            e.changePointSize(size.get(e))
-            
+            if(e.visible){
+                e.material.pointSizeType = sizeType
+                e.changePointSize(size.get(e))
+            }
+            e.visible = visiMap.get(e)  
         })
     }else{
         /* if(viewer.viewports.filter(e=>!e.noPointcloud).length>1){
@@ -794,7 +805,7 @@ Potree.updatePointClouds =  function(pointclouds,camera, areaSize  ){
 Potree.updateVisibilityStructures = function(pointclouds, camera, areaSize) {
 	let frustums = [];
 	let camObjPositions = [];
-	let priorityQueue = new BinaryHeap(function (x) { return 1 / x.weight; });
+	let priorityQueue = new BinaryHeap(function (x) { return 1 / x.weight; });//二叉堆。
 
 	for (let i = 0; i < pointclouds.length; i++) {
 		let pointcloud = pointclouds[i];
@@ -833,11 +844,12 @@ Potree.updateVisibilityStructures = function(pointclouds, camera, areaSize) {
 		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 (pointcloud.visible && pointcloud.root !== null) {
 			priorityQueue.push({pointcloud: i, node: pointcloud.root, weight: Number.MAX_VALUE});
-		}
+		}  */                                   
+		if (pointcloud.visible || !pointcloud.hasDepthTex && pointcloud.unvisibleReasons && pointcloud.unvisibleReasons.length == 1 && pointcloud.unvisibleReasons[0].reason == 'displayMode'   &&  pointcloud.root !== null) {//改 visible -> 
+			priorityQueue.push({pointcloud: i, node: pointcloud.root, weight: Number.MAX_VALUE});
+		} 
 
 		// hide all previously visible nodes
 		// if(pointcloud.root instanceof PointCloudOctreeNode){
@@ -857,7 +869,7 @@ Potree.updateVisibilityStructures = function(pointclouds, camera, areaSize) {
 		'camObjPositions': camObjPositions,
 		'priorityQueue': priorityQueue
 	};
-};
+}; 
 
 
 Potree.updateVisibility = function(pointclouds, camera, areaSize){
@@ -892,9 +904,11 @@ Potree.updateVisibility = function(pointclouds, camera, areaSize){
 	let pointcloudTransformVersion = Potree._pointcloudTransformVersion;
 	for(let pointcloud of pointclouds){
 
-		if(!viewer.getObjVisiByReason(pointcloud, 'datasetSelection')){//改 visible ->  
+		if(pointcloud.hasDepthTex ? !pointcloud.visible : !viewer.getObjVisiByReason(pointcloud, 'datasetSelection')){//改 visible ->  
 			continue;
-		}
+		} 
+        
+        //if(!pointcloud.visible) continue
 
 		pointcloud.updateMatrixWorld();
 
@@ -916,7 +930,7 @@ Potree.updateVisibility = function(pointclouds, camera, areaSize){
 	}
 
 	while (priorityQueue.size() > 0) {
-		let element = priorityQueue.pop();//其实是拿第一个, 再把最后一个放到前面
+		let element = priorityQueue.pop(); //取出权重最大的一个
          
 		let node = element.node;
 		let parent = element.parent;
@@ -938,7 +952,7 @@ Potree.updateVisibility = function(pointclouds, camera, areaSize){
 		let level = node.getLevel();
 		let visible = insideFrustum;
 		visible = visible && !(numVisiblePoints + node.getNumPoints() > Potree.pointBudget);
-		visible = visible && !(numVisiblePointsInPointclouds.get(pointcloud) + node.getNumPoints() > pointcloud.pointBudget);
+		visible = visible && !(numVisiblePointsInPointclouds.get(pointcloud) + node.getNumPoints() > pointcloud.pointBudget); // pointcloud.pointBudget一直是Infinity
 		visible = visible && level <= maxLevel; //< 改为 <=
 		//visible = visible || node.getLevel() <= 2;
 
@@ -986,13 +1000,9 @@ Potree.updateVisibility = function(pointclouds, camera, areaSize){
             //}
 
             let frustum = new THREE.Frustum(pxPlane, nxPlane, pyPlane, nyPlane, pzPlane, nzPlane);
-            let intersects = frustum.intersectsBox(box);
+            let intersects = frustum.intersectsBox(box); //node的bounding
 
-            /* if(intersects){
-                    numIntersecting++;
-                }
-                numIntersectionVolumes++;
-            */
+             
             return !!intersects
         }
 
@@ -1038,52 +1048,7 @@ Potree.updateVisibility = function(pointclouds, camera, areaSize){
                 visible = false  
             }
         }
-        */
-
-
-
-
-
-            /*let clipBoxes = pointcloud.material.clipBoxes;
-		 if(true && clipBoxes.length > 0){
-
-			//node.debug = false;
-
-			let numIntersecting = 0;
-			let numIntersectionVolumes = 0;
-
-			//if(node.name === "r60"){
-			//	var a = 10;
-			//}
-
-			for(let clipBox of clipBoxes){
-			}
-
-			let insideAny = numIntersecting > 0;
-			let insideAll = numIntersecting === numIntersectionVolumes;
-
-			if(pointcloud.material.clipTask === ClipTask.SHOW_INSIDE){
-				if(pointcloud.material.clipMethod === ClipMethod.INSIDE_ANY && insideAny){
-					//node.debug = true
-				}else if(pointcloud.material.clipMethod === ClipMethod.INSIDE_ALL && insideAll){
-					//node.debug = true;
-				}else{
-					visible = false;
-				}
-			} else if(pointcloud.material.clipTask === ClipTask.SHOW_OUTSIDE){
-				//if(pointcloud.material.clipMethod === ClipMethod.INSIDE_ANY && !insideAny){
-				//	//visible = true;
-				//	let a = 10;
-				//}else if(pointcloud.material.clipMethod === ClipMethod.INSIDE_ALL && !insideAll){
-				//	//visible = true;
-				//	let a = 20;
-				//}else{
-				//	visible = false;
-				//}
-			}
-			 
-
-		}*/
+        */ 
 
 		// visible = ["r", "r0", "r06", "r060"].includes(node.name);
 		// visible = ["r"].includes(node.name);
@@ -1116,13 +1081,13 @@ Potree.updateVisibility = function(pointclouds, camera, areaSize){
 				node = pointcloud.toTreeNode(node, parent);
 				loadedToGPUThisFrame++;
 			} else {
-				unloadedGeometry.push({pointcloud,node});
+				unloadedGeometry.push({pointcloud,node});   //加载点云
 				visibleGeometry.push(node);
 			}
 		}
 
 		if (node.isTreeNode()) {
-			Potree.lru.touch(node.geometryNode);
+			Potree.lru.touch(node.geometryNode);//在缓存中计入点云
 			node.sceneNode.visible = true;
 			node.sceneNode.material = pointcloud.material;
 
@@ -1182,13 +1147,14 @@ Potree.updateVisibility = function(pointclouds, camera, areaSize){
 				
 				
 				let radius = sphere.radius;
-				
+                 
 				let fov = (camera.fov * Math.PI) / 180;
 				let slope = Math.tan(fov / 2);
 				let projFactor = (0.5 * domHeight) / (slope * distance);
 				let screenPixelRadius = radius * projFactor;
-				
-				if(screenPixelRadius < pointcloud.minimumNodePixelSize){
+				//screenPixelRadius 和 domHeight 成正比,所以手机横屏后screenPixelRadius会变小。这是正常的,因为vhov不变,相同物体高度在横屏后高度变小,所需要的密度不需要那么高了。但hfov横屏后扩大,所以可见的node范围变大,又增加了一些可见node;只是总体的可见node还是减少了。
+				//使用hfov和domWidth计算结果相同。
+                if(screenPixelRadius < pointcloud.minimumNodePixelSize){
 					continue;
 				}
 			
@@ -1200,14 +1166,14 @@ Potree.updateVisibility = function(pointclouds, camera, areaSize){
 			} else {
 				// TODO ortho visibility
 				let bb = child.getBoundingBox();				
-				let distance = child.getBoundingSphere().center.distanceTo(camObjPos);
+				let distance = child.getBoundingSphere().center.distanceTo(camObjPos); //先加载中间然后四周
 				let diagonal = bb.max.clone().sub(bb.min).length();
 				//weight = diagonal / distance;
-
+                
 				weight = diagonal;
 			}
 
-			priorityQueue.push({pointcloud: element.pointcloud, node: child, parent: node, weight: weight});
+			priorityQueue.push({pointcloud: element.pointcloud, node: child, parent: node, weight: weight}); //貌似好像二叉堆中子节点和父节点没什么关系,就只是为了方便排序层层遍历
 		}
 	}// end priority queue loop
 
@@ -1230,9 +1196,12 @@ Potree.updateVisibility = function(pointclouds, camera, areaSize){
 		lowestSpacing: lowestSpacing
 	};
 };
-
- 
-
+/* 
+    note:
+    缓存中的点数 Potree.lru.numPoints 会 大于 每个点云显示的numVisiblePoints之和。
+    当超出缓冲区最大点云数时,加载的点云节点会被dispose彻底消除;否则,隐藏的节点就会等待再次被使用显示
+    要降低卡顿,就只需要降低Potree.pointBudget即可。为了level显示均匀,还能另外设置整体maxLevel
+ */
 {//HQSplatRenderer
     let oldInit = HQSplatRenderer.prototype.init;
     HQSplatRenderer.prototype.init = function(){
@@ -1632,28 +1601,22 @@ PointCloudOctreeGeometryNode.prototype.traverse = function(t, e){//add from navv
 Object.assign( PointCloudOctreeGeometry.prototype, THREE.EventDispatcher.prototype );
 
 LRU.prototype.freeMemory = function(){
+    
     if (this.elements <= 1) {
         return;
-    }
-
-    /* while (this.numPoints > Potree.pointLoadLimit) {
-        let element = this.first;
-        let node = element.node;
-        this.disposeDescendants(node);
-    } */ 
+    } 
     
-    //改成navvis的,使用pointBudget,否则四屏点云闪烁。 
-    let max = /* this.pageVisible ?  */viewer.viewports.length * 2 * Potree.pointBudget// : 1000
+    //改成navvis的,使用pointBudget,否则四屏点云闪烁。 (似乎要比updateVisiblede的node时限制要宽些,作为缓存继续存着。否则会闪烁)
+    let max =  viewer.viewports.length * 2 * Potree.pointBudget// : 1000  // this.pageVisible ?  
        
-    for (; this.numPoints > max;  ) {//要根据屏幕数量来增加pointBudget
+    for (; this.numPoints > max;  ) {//应该是从子node删除
         var node = this.getLRUItem();
-        node && this.disposeSubtree(node)
+        node && this.disposeDescendants(node); //this.disposeSubtree(node)
     } 
     
-}
-
-
-LRU.prototype.disposeSubtree = function(t) {//add from navvis 25.js
+} 
+/* 
+LRU.prototype.disposeSubtree = function(t) {//add from navvis 25.js  和原来的disposeDescendants功能一样
     var e = [t];
     t.traverse((function(t) {
         t.loaded && e.push(t)
@@ -1663,7 +1626,7 @@ LRU.prototype.disposeSubtree = function(t) {//add from navvis 25.js
         o.dispose(),
         this.remove(o)
     }
-}
+}*/
 
 VolumeTool.prototype.update = function(){}
 

+ 11 - 2
src/custom/settings.js

@@ -101,47 +101,54 @@ const config = {//配置参数   不可修改
         mapHeight : -1000,//要比点云低。最低
         cameraHeight : 1000,  //最高  ,注意(如sitemodel)其他的物体不能超过这个高度
     },
-    
+    minNodeSize:30, // perspectiveCamera允许加载的node的最小可见像素宽度。越大越省性能
     
     pointDensity:{
         magnifier:{  
             maxLevelPercent: 1,
-            pointBudget : 8*1000*1000, 
+            pointBudget : 8*1000*1000,  
         },
         panorama:{//显示全景时的漫游。因为点只能显示1个像素的大小,所以必须很密集,但又要限制点的数量
             maxLevelPercent: 0.6,
             pointBudget : /* 4*1000*1000// */browser.isMobile() ?  0.1*1000*1000 :  0.4*1000*1000,  //点云总最大数
+            minNodeSize : 100,
         }, 
         
         fourViewports:{//分四屏时防止卡顿
             maxLevelPercent: 0.4,  
             pointBudget :1*1000*1000, // 只要限制这个就足够 (为什么分屏focus区域不同会闪烁,navvis不会)(navvis:maxLevel:5,pointBudget:1*1000*1000)
+            minNodeSize : 70,
         }, 
         fourViewportsMain:{//分四屏时防止卡顿
             maxLevelPercent: 0.8,  
             pointBudget :1*1000*1000, // 只要限制这个就足够 (为什么分屏focus区域不同会闪烁,navvis不会)(navvis:maxLevel:5,pointBudget:1*1000*1000)
+            minNodeSize : 70,
         }   
         ,
         panoEdit:{
             maxLevelPercent: 1,  //在远处时由于pointBudget限制而展示稀疏,凑近时就变为最高质量了
             pointBudget :4*1000*1000, //避免卡顿
             percentByUser:true,
+            minNodeSize : 50,
         },
         
         low:{//highPerformance
             maxLevelPercent: 0.4, //最小为0
             percentByUser:true, //如果用户定义了percent,使用用户的
             pointBudget : browser.isMobile() ? 1*1000*1000 : 2*1000*1000, 
+            minNodeSize : browser.isMobile() ? 120 : 100 ,
         }, 
         middle:{//balanced  //不同场景相同级别所产生的numVisibleNodes和numVisiblePoints不同,如果分层比较细,可能要到level8才能看清,那么level5看到的点就很大且很少,如隧道t-e2Kb2iU
             maxLevelPercent: 0.7,
             percentByUser:true,
             pointBudget:browser.isMobile() ? 2*1000*1000 : 4*1000*1000, 
+            minNodeSize : browser.isMobile() ? 100 : 70 ,
         },
         high:{//highQuality
             maxLevelPercent: 1, 
             percentByUser:true,
             pointBudget:browser.isMobile() ? 4*1000*1000 : 8*1000*1000,
+            minNodeSize : browser.isMobile() ? 60 : 30 ,
         }
         //browser.isMobile() 时要不要限制下pointBudget,还是让用户自己调低质量?
         //minNodeSize?
@@ -425,10 +432,12 @@ let settings = {//设置   可修改
     boundAddObjs:false,
     intersectOnObjs:false,
     intersectWhenHover:true,
+    depTexLocBindDataset: true,//是否在pano模式下,使用深度图得到intersect的话,改intersect能属于该pano所在的点云。也就相当于在全景模式下intersect的点属于该全景图
 
     notAdditiveBlending:false, //点云是否使用普通的blend, 否则会曝光过渡
     precision:2,  // 两位小数
     
+    
     testV4url:false, //v4的全景图等路径不一样 scene_view_data
 }
   

+ 1 - 1
src/custom/utils/Common.js

@@ -321,7 +321,7 @@ var Common = {
     
 }  
 
-
+Potree.Common = Common
 
   
 export default Common 

+ 29 - 61
src/custom/utils/History.js

@@ -10,99 +10,67 @@ class History extends THREE.EventDispatcher{
         super()
         
         this.undoList = []   
-        this.redoList = []
-        //this.initializedMasters = []// [objects1, objects2,....]
-        this.applyData = o.applyData
-        this.getData = o.getData
-        this.prepareRecord = true
-        this.currentData 
+        this.redoList = [] 
+        this.applyData = o.applyData    //应用数据的方法
+        this.getData = o.getData        //获取数据的方法
+        
+        this.dataBefore 
     }
     
-    undo(){ 
+    undo(){//回退 
         let length = this.undoList.length
-        /* if(length>1){  
-            let last = this.undoList.pop();
-            this.redoList.push(last);
-            let now = this.undoList[length-2];
-            this.applyData && this.applyData(now.data) 
-            this.dispatchEvent('undo')
-            console.log('undo',now.data)
-        }  */
+         
         if(length>0){  
             let last = this.undoList.pop(); 
-            this.applyData && this.applyData(last) 
-            this.redoList.push(this.currentData);
-            this.currentData = last
+            this.applyData && this.applyData(last.before) 
+            this.redoList.push(last);
+             
             this.dispatchEvent('undo')
-            console.log('undo',last)
+            //console.log('undo',last)
         } 
     }
     
     
-    redo(){ 
+    redo(){//撤销回退 
         let length = this.undoList.length
         let last = this.redoList.pop();
         if(last){
             //注意:每行的顺序不能乱
-            this.undoList.push(this.currentData) 
-            this.currentData = last
-            this.applyData && this.applyData(this.currentData) 
+            this.undoList.push(last)  
+            this.applyData && this.applyData(last.after) 
             this.dispatchEvent('redo')
-            console.log('redo',last)
+            //console.log('redo',last)
         }
     }
      
     
-    beforeChange(o/* , masters, simpleEqualClass */){
-        /* if(!this.initializedMasters.find(e=>Common.ifSame(e, masters, simpleEqualClass))){  
-            let data = this.getData(o)
-            console.log('beforeChange',data )
-            this.writeIn(data, masters) 
-            this.initializedMasters.push(masters)
-            
-        }  */
-        
-        if(this.prepareRecord){
+    beforeChange(o){//在变化之前(可能执行好几次直到变化完,但只有第一次有效)。 o的内容完全根据getData怎么定义
+        if(!this.dataBefore){
             let data = this.getData(o)
-            this.writeIn(data)
-            this.prepareRecord = false
+            this.dataBefore = data 
         } 
     } 
     
-    afterChange(o/* , masters  */){ 
-        //let data = this.getData(o)
-        //console.log('afterChange',data )
-        //this.writeIn(data , masters ) 
-        this.currentData = this.getData(o)
-        this.prepareRecord = true    
+    afterChange(o){//变化结束,从beforeChange到此算一次操作。
+        if(this.dataBefore){
+            this.writeIn({before:this.dataBefore, after:this.getData(o)}     ) //写入某物体变化前和变化后的状态
+            this.dataBefore = null  
+        } 
     }
     
-    writeIn(data/*  , masters  */){
-        
-        /* this.redoList.forEach(e=>{ 
-            if(!this.undoList.some(item=>Common.ifSame(item.masters, e.masters))){//删除该主体
-                let masters = this.initializedMasters.find(masters=>Common.ifSame(e.masters, masters))
-                if(masters){
-                    let index = this.initializedMasters.indexOf(masters)
-                    this.initializedMasters.splice(index,1)
-                    console.log('删除该主体',masters)
-                }
-            }  
-        }) */
-        
-        this.redoList.length = 0; //一旦录入新的操作,就不允许恢复了
+    writeIn(data ){ 
+        this.redoList.length = 0; //一旦录入新的操作,就不允许undo了
          
-        this.undoList.push(data/* {data,masters} */);
-        console.log('新增undo', data)    
+        this.undoList.push(data );
+        //console.log('新增undo', data)    
     }
     
     
     clear(){ 
         this.redoList.length = 0 
         this.undoList.length = 0 
-    }
-    
-    
+        this.dataBefore = null
+    } 
     
 }
 

+ 5 - 3
src/custom/viewer/ViewerNew.js

@@ -250,7 +250,7 @@ export class Viewer extends ViewerBase{
             this.isFlipYZ = false;
             this.useDEMCollisions = false;
             this.generateDEM = false;
-            this.minNodeSize = 30;
+            this.minNodeSize = 30;   //允许加载的node的最小可见像素宽度。越大越省性能
             this.edlStrength = 1.0;
             this.edlRadius = 1.4;
             this.edlOpacity = 1.0;
@@ -596,6 +596,8 @@ export class Viewer extends ViewerBase{
                             pointBudget = config.pointBudget
                         }
                         
+                        
+                        viewer.setMinNodeSize(config.minNodeSize || Potree.config.minNodeSize)
                         viewer.setPointBudget(pointBudget );
                         //Potree.maxPointLevel = config.maxLevel
                         
@@ -1129,7 +1131,7 @@ export class Viewer extends ViewerBase{
 		}
 	}
 
-	setPointBudget (value) {
+	setPointBudget (value) { //pointBudget: 每次刷新显示点数量的最大值。  缓存中的点数量也跟此有关,但大于这个数值。
 		if (Potree.pointBudget !== value) {
 			Potree.pointBudget = parseInt(value);
 			this.dispatchEvent({'type': 'point_budget_changed', 'viewer': this});
@@ -2860,7 +2862,7 @@ export class Viewer extends ViewerBase{
                 
                 view.beforeRender && view.beforeRender()
                 
-                this.updateViewPointcloud(params.camera, view.resolution2, true)
+                this.updateViewPointcloud(params.camera, view.resolution, true)
                 
                 params.background = view.background
                 params.backgroundColor = view.backgroundColor

+ 3 - 3
src/custom/viewer/Viewport.js

@@ -58,8 +58,8 @@ export default class Viewport{
             this.previousState = {
                 projectionMatrix: this.camera.projectionMatrix.clone(),//worldMatrix在this.control时归零了所以不用了吧,用position和qua也一样
                 position: this.camera.position.clone(),
-                quaternion: this.camera.quaternion.clone()
-                
+                quaternion: this.camera.quaternion.clone(),
+                 
             }; 
         }
         let projectionChanged = true
@@ -86,6 +86,6 @@ export default class Viewport{
         
         this.resolution2.copy(this.resolution).multiplyScalar(this.pixelRatio || window.devicePixelRatio)
          
-        this.offset.set(wholeW,wholeH).multiply(new THREE.Vector2(this.left,this.bottom)).multiplyScalar(window.devicePixelRatio) 
+        this.offset.set(wholeW,wholeH).multiply(new THREE.Vector2(this.left,this.bottom))//.multiplyScalar(window.devicePixelRatio) 
     }
 }

+ 2 - 1
src/materials/shaders/depthBasic.fs

@@ -50,7 +50,8 @@ void main() {
 
         // The coordinates of the current fragment in the depth texture
         vec2 depthTxtCoords = vec2(gl_FragCoord.x-viewportOffset.x,  gl_FragCoord.y - viewportOffset.y) / resolution;
-     
+        //gl_FragCoord大小为 viewport client大小 
+        
         // The linear depth value of the pixel occupied by this fragment in the depth buffer
         float textureDepth = convertToLinear(texture2D(depthTexture, depthTxtCoords).r);
 

+ 19 - 15
src/navigation/InputHandlerNew.js

@@ -401,8 +401,7 @@ export class InputHandler extends THREE.EventDispatcher {
         if(isTouch || !Potree.settings.intersectWhenHover ){ 
             this.hoveredElements = this.getHoveredElements();
             this.intersect = this.getIntersect(viewport)
-            //this.intersect = this.getWholeIntersect()
-            
+            //this.intersect = this.getWholeIntersect() 
         }
         
         if(!viewport)return 
@@ -800,6 +799,10 @@ export class InputHandler extends THREE.EventDispatcher {
                 intersect = Utils.getIntersect(camera, [viewer.images360.cube], this.pointer, raycaster) 
             } 
             intersectPoint = viewer.images360.depthSampler.sample(intersect, prop.pano, !!prop.point)  //可能不准确, 因pano可能未加载depthTex
+            if(intersectPoint && Potree.settings.depTexLocBindDataset){
+                intersectPoint.pointcloud = (prop.pano || viewer.images360.currentPano).pointcloud
+                //在全景模式下,虽然深度图上的点可能对应别的pointcloud,但因为是在当前全景图处得到的,所以即使将原本对应的点云移走,该点也不移动是有道理的。它可以永远跟着该全景图。
+            }
         }
         
         let getByCloud = ()=>{
@@ -828,22 +831,26 @@ export class InputHandler extends THREE.EventDispatcher {
                 viewport.view.applyToCamera(camera)
                 this.pointer.copy(prop.pointer)
                 this.mouse.copy(prop.mouse)
-            } 
-            
-            
+            }  
         }
         
+        
+        
         let canUseDepthTex = Potree.settings.displayMode == 'showPanos' && viewer.images360.currentPano.pointcloud.hasDepthTex  && viewport == viewer.mainViewport && !usePointcloud 
         
         if(canUseDepthTex && !this.isMeasuring){
             getByDepthTex()
         }else{
             getByCloud() 
-            if(!intersectPoint && canUseDepthTex  ){//得不到的话再使用 getByDepthTex 得一次
+            if(!intersectPoint && canUseDepthTex  ){  //若在测量,先尝试点云,再用全景
                 getByDepthTex()
             }
-        }
-          
+        }  
+        
+        
+                   
+
+         
         //console.log(viewport.name , intersectPoint &&  intersectPoint.location )
         let intersect
         let intersectOnModel, allElements
@@ -951,9 +958,9 @@ export class InputHandler extends THREE.EventDispatcher {
         let intersect 
         
         
-        if(e.onlyGetIntersect ||  Potree.settings.intersectWhenHover && (!this.drag || this.drag.object || viewport.alignment ) ){ //没有拖拽物体,但按下鼠标了的话,不intersect
+        if(e.onlyGetIntersect ||  Potree.settings.intersectWhenHover && (!this.drag || this.drag.object || viewport.alignment ) ){ //没有拖拽物体,但按下鼠标了的话,不intersect。触屏的就能直接避免intersect
         
-            let dontIntersect =  this.drag && viewport.alignment/*  && Potree.settings.editType == 'pano'  */|| isFlying/* viewer.images360.flying */ // flying 时可能卡顿
+            let dontIntersect =  this.drag && viewport.alignment || isFlying /* viewer.images360.flying */ // flying 时可能卡顿
             //console.log('dontIntersectPointcloud',dontIntersectPointcloud)
             intersect = this.getIntersect(viewport,  e.onlyGetIntersect, e.pickWindowSize, !!dontIntersect, e.whichPointcloud) //数据集多的时候卡顿
             //console.log('intersectPoint', intersectPoint)
@@ -970,10 +977,7 @@ export class InputHandler extends THREE.EventDispatcher {
             return intersect
         }
         e.preventDefault();
-        
-        
-        
-        
+         
         
         /* if(intersectPoint && intersectPoint.pointcloud){
             console.log(intersectPoint.pointcloud.name)
@@ -1335,7 +1339,7 @@ export class InputHandler extends THREE.EventDispatcher {
             intersections = intersections.filter(e=>{
                 let material = e.object.material
                 
-                return (e.object.pickDontCheckDis || material.depthTest == false || material.depthWrite == false) && !material.useDepth  //!material.depthTestWhenPick
+                return e.object.pickDontCheckDis || ( material.depthTest == false || material.depthWrite == false) && !material.useDepth  //!material.depthTestWhenPick
                  || ( material.useDepth ? e.distance < this.intersect.distance + material.uniforms.occlusionDistance.value : e.distance < this.intersect.distance )
             }) 
         }

+ 5 - 11
src/utils/TransformationToolNew.js

@@ -147,20 +147,14 @@ export class TransformationTool extends THREE.EventDispatcher{
                     return data
                 } 
             })
-            //this.prepareRecord = true
-            this.addEventListener('transformed', (e)=>{
-                /* if(this.prepareRecord){
-                    let object = viewer.transformationTool.selection[0]
-                    this.history.writeIn({object, matrix:e.matrixBefore.clone()})
-                    this.prepareRecord = false
-                } */
+      
+            this.addEventListener('transformed', (e)=>{ 
                 let object = viewer.transformationTool.selection[0]
-                this.history.beforeChange({object, matrix:e.matrixBefore.clone()},[object],[Potree.BoxVolume])
+                this.history.beforeChange({object, matrix:e.matrixBefore.clone()} )
             })
-            this.addEventListener('stopDrag', (e)=>{
-                //this.prepareRecord = true
+            this.addEventListener('stopDrag', (e)=>{ 
                 let object = viewer.transformationTool.selection[0]
-                object && this.history.afterChange({object, matrix:object.matrix.clone()},[object])
+                object && this.history.afterChange({object, matrix:object.matrix.clone()} )
             })
             viewer.inputHandler.addEventListener('keydown', (e)=>{
                 if(e.keyCode == 90 && e.event.ctrlKey){//Z

+ 3 - 3
src/viewer/EDLRendererNew.js

@@ -66,7 +66,7 @@ export class EDLRenderer{//Eye-Dome Lighting 眼罩照明
         if(Features.EXT_DEPTH.isSupported()){  
             let viewport = e.viewport
              
-            this.getRtEDL(viewport).setSize(viewport.resolution2.x, viewport.resolution2.y);
+            this.getRtEDL(viewport).setSize(  viewport.resolution.x, viewport.resolution.y  );   //理论上可以是任意尺寸,但会影响精度,且aspect最好和渲染的一致
         }
 	}
 
@@ -116,7 +116,7 @@ export class EDLRenderer{//Eye-Dome Lighting 眼罩照明
         var rtEDL = this.rtEDLs.get(viewport)
         if(!rtEDL){
             if(Features.EXT_DEPTH.isSupported()){ 
-                rtEDL = new THREE.WebGLRenderTarget(viewport.resolution2.x, viewport.resolution2.y, {
+                rtEDL = new THREE.WebGLRenderTarget(viewport.resolution.x, viewport.resolution.y, {
                     minFilter: THREE.NearestFilter,
                     magFilter: THREE.NearestFilter,
                     format: THREE.RGBAFormat,
@@ -183,7 +183,7 @@ export class EDLRenderer{//Eye-Dome Lighting 眼罩照明
         
         const viewer = this.viewer; 
 		let camera = params.camera ? params.camera : viewer.scene.getActiveCamera();
-		const resolution = params.viewport ? params.viewport.resolution2 : this.viewer.renderer.getSize(new THREE.Vector2());
+		const resolution = params.viewport ? params.viewport.resolution : this.viewer.renderer.getSize(new THREE.Vector2());//突然发现mobile用resolution2点云会放大
 		
         
         //viewer.dispatchEvent({type: "render.pass.begin",viewer: viewer});

+ 3 - 2
改bug的历史.txt

@@ -1,9 +1,10 @@
 
+2022.11.24
 
 
 
-
-
+全景模式为什么有时候变卡: 导航会一直加载点云,因一直getPointByScreen
+改完之后过渡很流畅。在此之前还将漫游模式的visibleNodes清空了,仅在不支持depthTex时length才不为0
 
 
 2022.8.30