Ver código fonte

getIntersect 参数调整为{}

xzw 1 ano atrás
pai
commit
2926884142

+ 3 - 3
src/ExtendPointCloudOctree.js

@@ -76,7 +76,7 @@ export class ExtendPointCloudOctree extends PointCloudOctree{
             this.nodeMaxLevel = level 
             //viewer.dispatchEvent({type:'updateNodeMaxLevel', pointcloud: this, nodeMaxLevel:level}) 
              
-            //console.log('updateNodeMaxLevel ' + this.dataset_id + " : "+ this.nodeMaxLevel)                
+             console.log('updateNodeMaxLevel ' + this.dataset_id + " : "+ this.nodeMaxLevel)                
               
             this.setPointLevel()//重新计算
              
@@ -195,7 +195,7 @@ export class ExtendPointCloudOctree extends PointCloudOctree{
         let min = Math.log2(this.material.spacing / spacing.max); //有见过最大是0.01368 
         let max = Math.log2(this.material.spacing / spacing.min); //大部分是 0.006
         //console.log('predictNodeMaxLevel:', this.name ,  min, max ) 
-    
+        //只对深时相机,其他相机不准
     
         return {min, max}
     } 
@@ -551,7 +551,7 @@ export class ExtendPointCloudOctree extends PointCloudOctree{
             num_ = Math.pow(num_, 1.05) * 6 
              
             
-            nodeMaxLevel = this.testMaxNodeCount >= Potree.config.testNodeCount1 ? this.nodeMaxLevel : this.nodeMaxLevelPredict.max //防止刚开始因nodeMaxLevel没涨完,导致过大的点云突然出现
+            nodeMaxLevel = this.testMaxNodeCount >= Potree.config.testNodeCount1 ? this.nodeMaxLevel : Math.max(this.nodeMaxLevel, this.nodeMaxLevelPredict.max )//防止刚开始因nodeMaxLevel没涨完,导致过大的点云突然出现
             
             if(sizeFitToLevel || Potree.settings.sizeFitToLevel){//按照点云质量来调整的版本:    近似将pointSizeType换成ADAPTIVE
                 let str = this.temp.pointSize+':'+this.maxLevel+':'+ nodeMaxLevel

+ 5 - 3
src/PotreeRendererNew.js

@@ -772,8 +772,10 @@ export class Renderer {
             
             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,深度会错乱。 
+                /* gl.enable(gl.DEPTH_TEST);
+                gl.depthMask(true); //如果不开启depthWrite, 深度会错乱。  */ //无解
+                 gl.disable(gl.DEPTH_TEST);
+                 gl.depthMask(true);  
             }else{
                 gl.blendFunc(gl.SRC_ALPHA, gl.ONE); //AdditiveBlending   原本
                 gl.disable(gl.DEPTH_TEST);
@@ -1681,7 +1683,7 @@ export class Renderer {
 		const traversalResult = this.traverse(scene);
         
         //排序
-        if(Potree.settings.notAdditiveBlending){//add 
+        if(params.notAdditiveBlending){//add 
             
             traversalResult.octrees.forEach(tree=>{
                 if(tree.material.opacity==1){

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

@@ -183,7 +183,7 @@ var Clip = {
                             }
 
                             
-                            if(Clip.switchMapCount == 0 || !Potree.Utils.getPos2d(viewer.scene.view.position, viewer.mapViewer.camera, viewer.mapViewer.renderArea, viewer.mapViewer.viewports[0]).inSight
+                            if(Clip.switchMapCount == 0 || !Potree.Utils.getPos2d(viewer.scene.view.position, viewer.mapViewer.viewports[0], viewer.mapViewer.renderArea).inSight
                               ||  !Potree.Utils.isInsideFrustum(boundingBox, viewer.mapViewer.camera)){ //要使box框和游标都在屏幕内。因为游标是3d的当前位置,很可能是准备去框住的位置
                                 let bound = boundingBox.clone()
                                     bound.expandByPoint(viewer.scene.view.position)

+ 3 - 2
src/custom/modules/mergeModel/MergeEditor.js

@@ -166,11 +166,12 @@ let MergeEditor = {
                 this.showModelOutline(this.selected,!!this.selected)
             } 
         })
-        viewer.fxaaPass.enabled = false//viewer.ssaaRenderPass.enabled = false 
+        //viewer.fxaaPass.enabled = false//viewer.ssaaRenderPass.enabled = false 
         viewer.outlinePass.enabled = true
         //Potree.settings.intersectWhenHover = false
         //Potree.Utils.updateVisible(viewer.reticule, 'force', false)
-        
+        viewer.composer.scaleRatio = 1
+        viewer.composer.readTarget = false
         viewer.mainViewport.camera.near = 0.05; // too small will result in z-fighting
         
         viewer.addEventListener('updateModelBound', (e)=>{

+ 3 - 1
src/custom/modules/panos/Images360.js

@@ -1003,7 +1003,9 @@ export class Images360 extends THREE.EventDispatcher{
             return this.depthSampler.sample( {dir }, pano, true )
         }else{
             origin = origin || pano.position
-            return viewer.inputHandler.getIntersect(viewer.inputHandler.hoverViewport, true, null, null, true, {
+            return viewer.inputHandler.getIntersect({
+                viewport:viewer.inputHandler.hoverViewport, 
+                onlyGetIntersect:true,  usePointcloud:true, 
                 point: origin.clone().add(dir),
                 cameraPos: origin
             })

+ 1 - 1
src/custom/objects/Label.js

@@ -33,7 +33,7 @@ class Label  extends THREE.EventDispatcher{
      
     update(){
         if(!this.position || this.elem.hasClass('unvisible'))return
-        var p = Utils.getPos2d(this.position,this.camera,this.dom, viewer.mainViewport);
+        var p = Utils.getPos2d(this.position, viewer.mainViewport,this.dom);
         if(!p.trueSide){
             this.elem.addClass("hide");  return;
         }

+ 2 - 2
src/custom/objects/Magnifier.js

@@ -220,7 +220,7 @@ export default class Magnifier extends THREE.Object3D {//放大镜or望远镜
         viewer.scene.view.addEventListener('flyingDone',()=>{
             if(!this.visible)return
             let pickWindowSize = 100
-            let intersect = viewer.inputHandler.getIntersect(viewer.mainViewport, viewer.mainViewport.camera, true, pickWindowSize )
+            let intersect = viewer.inputHandler.getIntersect({viewport:viewer.mainViewport,  usePointcloud:true, pickWindowSize} )
             this.update(intersect && intersect.location)
         })
     }
@@ -267,7 +267,7 @@ export default class Magnifier extends THREE.Object3D {//放大镜or望远镜
          
         //自身位置 
         //let pos2d = viewer.inputHandler.pointer.clone();   //跟随鼠标 
-        let pos2d = Potree.Utils.getPos2d(aimPos, playerCamera, viewer.renderArea, viewer.mainViewport).vector   //更新目标点的实时二维位置
+        let pos2d = Potree.Utils.getPos2d(aimPos, viewer.mainViewport, viewer.renderArea).vector   //更新目标点的实时二维位置
         let margin = 0.4, maxY = 0.4
         let screenPos = pos2d.clone().setY(pos2d.y + (pos2d.y>maxY ? -margin : margin ))
         

+ 1 - 1
src/custom/objects/Reticule.js

@@ -5,7 +5,7 @@ import math from '../utils/math.js'
 
 
 let texLoader = new THREE.TextureLoader()
-let defaultOpacity =  0.5
+let defaultOpacity =  0.6
 let Buttons = Potree.defines.Buttons
 
 

+ 3 - 3
src/custom/objects/Sprite.js

@@ -165,7 +165,7 @@ export default class Sprite extends THREE.Mesh{
                 }
                 
                 
-                let r1 = Potree.Utils.getPos2d(center, camera, viewer.renderArea, e.viewport); 
+                let r1 = Potree.Utils.getPos2d(center,   e.viewport,  viewer.renderArea ); 
                 if(!r1.trueSide)return  setVisi(false);// 但这句会使realVisible为false从而无法更新//console.error('!r1.trueSide') //中心点如果在背面直接不渲染了
                     
                 let r2, point2
@@ -174,7 +174,7 @@ export default class Sprite extends THREE.Mesh{
                 while(p2State != 'got' && p2StateHistory.length<10){ 
                     point2 = center.clone().add(this.root.lineDir.clone().multiplyScalar(len));
                      
-                    r2 = Potree.Utils.getPos2d(point2, camera, viewer.renderArea, e.viewport);  
+                    r2 = Potree.Utils.getPos2d(point2, e.viewport , viewer.renderArea  );  
                     if(!r2.trueSide){ //很少遇到点2在背面的
                         if(!p2StateHistory.includes('tooLong-reverse')){
                             p2State = 'tooLong-reverse'  //先尝试反向
@@ -323,7 +323,7 @@ export default class Sprite extends THREE.Mesh{
             var matrix2 = this.matrixMapRoot.get(e.viewport);
             this.root.matrix.copy(matrix2) 
         }
-        if(e.raycaster)console.log(3)  
+        
         e.raycaster && this.root.updateMatrixWorld(true)//渲染前会自动updateMatrixWorld,但raycaster不会
         //console.log(this.root.name + e.viewport.name + " : "+this.root.matrixWorld.elements)
     }

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

@@ -130,7 +130,7 @@ export default class HandleSvg extends THREE.EventDispatcher{
         let camera = viewer.scene.getActiveCamera() 
           
         
-        var p = Potree.Utils.getPos2d( this.position, camera , viewer.renderArea, viewer.mainViewport);
+        var p = Potree.Utils.getPos2d( this.position, viewer.mainViewport, viewer.renderArea);
         if(!p.trueSide){
             return this.svg.style.display = 'none'; 
         }

+ 38 - 29
src/custom/objects/tool/Measure.js

@@ -22,7 +22,7 @@ var markerMats;
 var lineMats;  
 var planeMats 
  
-const textSizeRatio = math.linearClamp(window.innerWidth * window.innerHeight , 360*720,   1920*1080, 0.7, 1)  //pc字显示大一些
+const textSizeRatio = math.linearClamp(window.outerWidth * window.outerHeight , 360*720,   1920*1080, 0.7, 1)  //pc字显示大一些
  
 const lineDepthInfo = {
     clipDistance : 4,//消失距离
@@ -39,19 +39,7 @@ const markerSizeInfo = {
 } */
 
 const labelSizeInfo = {width2d:200}
-/* 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, 
-    
-     
-    clipDistance : 20,//消失距离
-    occlusionDistance: 5,//变为backColor距离 
-    maxOcclusionFactor:0.7,
-    
-} */
+ 
 const mainLabelProp = { 
     //backgroundColor: {r: defaultColor.r*255, g: defaultColor.g*255, b: defaultColor.b*255, a:config.measure.default.opacity},
     backgroundColor: {r: 0, g: 0, b: 0, a:0}, 
@@ -76,19 +64,13 @@ const subLabelProp = {
     textColor: {r: textColor.r*255, g: textColor.g*255, b: textColor.b*255, a: 1.0},
     textBorderColor: {r:255, g: 255, b:255, a: 1.0},
     textBorderThick:3  ,
-    fontsize: 15 * textSizeRatio,  
+    fontsize: 14 * textSizeRatio,  
     renderOrder : 4, pickOrder:4,
     disToLine:-0.13,
 }
 
 
-/* const subLabelProp = { 
-    backgroundColor: {r: 255, g: 255, b: 255, a:1},
-    textColor: {r: 0, g: 0, b:0, a: 1.0},
-    fontsize:14, 
-    renderOrder : 4, pickOrder:4,
-}
- */
+ 
 
 const angle = THREE.Math.degToRad(5);//显示水平垂直辅助线的最小角度
 const guideShowMinAngle = {min: angle, max: Math.PI/2 - angle}
@@ -149,7 +131,7 @@ export class Measure extends ctrlPolygon{
         //addMarkers:
          
         this.initData(prop)
-        
+        this.pointsPos2d = new Map //屏幕上的二维坐标
          
         this.points_datasets || (this.points_datasets = []) //存每个点是哪个数据集
 
@@ -562,10 +544,16 @@ export class Measure extends ctrlPolygon{
         marker.pickOrder = marker.renderOrder = 3 
         marker.markerSelectStates = {} 
         marker.addEventListener('startDragging',(e)=>{
-            if(e.drag.dragViewport.name == 'MainView')viewer.inputHandler.dispatchEvent( {type: 'isMeasuring',v:true, cause:'startDragging'})
+            /*  if(e.drag.dragViewport.name == 'MainView') */viewer.inputHandler.dispatchEvent( {type: 'measuring',v:true, cause:'startDragging', situation:'dragging', object:this})
         })
         marker.addEventListener('drop',(e)=>{
-            viewer.inputHandler.dispatchEvent({type: 'isMeasuring',  v:false, cause:'stopDragging'}  )
+            viewer.inputHandler.dispatchEvent({type: 'measuring',  v:false, cause:'stopDragging', situation:'dragging', object:this}  )
+        
+            if(Potree.settings.adsorption){
+                this.isNew || viewer.viewports.forEach((viewport)=>{
+                    this.getPointsPos2d(viewport, true )//forceUpdate
+                })  
+            }
         })
         //marker.measure = this 
         let edge
@@ -588,7 +576,7 @@ export class Measure extends ctrlPolygon{
                 edge.addEventListener('click',()=>{
                     this.isNew || viewer.focusOnObject(this, 'measure')
                 })
-                
+                 
             }
             edge.addEventListener('addHoverEvent', addHoverEvent);
 		}
@@ -896,8 +884,15 @@ export class Measure extends ctrlPolygon{
     }
     
     createEdgeLabel(name, hasHoverEvent){
+        
+        let inf = {
+            sizeInfo: labelSizeInfo,  name:name||'edgeLabel', 
+        }
+        if(name && name.includes('Guide')){
+            inf.fontsize = 12
+        }
         const edgeLabel = new TextSprite(
-            $.extend(hasHoverEvent ? mainLabelProp : subLabelProp,{sizeInfo: labelSizeInfo,  name:name||'edgeLabel'})
+            $.extend({}, hasHoverEvent ? mainLabelProp : subLabelProp, inf)
         )
         if(hasHoverEvent){
             edgeLabel.addEventListener('mouseover',()=>{
@@ -1069,7 +1064,21 @@ export class Measure extends ctrlPolygon{
 	};
 
     
-    
+    getPointsPos2d(viewport, update){//获取屏幕上的二维坐标
+        let ps = this.pointsPos2d.get(viewport) 
+        if(update || !ps){
+            let points = this.points.map(e=>{
+                let p = Potree.Utils.getPos2d(e,  viewport, viewer.renderArea )
+                p.pos3d = e.clone(),  p.object = this
+                return p
+            }); 
+            
+            this.pointsPos2d.set(viewport, points)
+            console.log('updatePointsPos2d',this.uuid,viewport.name)
+        }
+        
+        return this.pointsPos2d.get(viewport) 
+    }
     
     transformData(prop){
         if(prop.measureType == 'Point'){ 
@@ -1202,7 +1211,7 @@ export class Measure extends ctrlPolygon{
         if(this.showTotalDis){
             this.totalDisLabel && this.totalDisLabel.setVisible(false) 
         }
-        viewer.inputHandler.dispatchEvent( {type:'isMeasuring', v:true, cause:'reDraw'}  )
+        viewer.inputHandler.dispatchEvent( {type:'measuring', v:true, cause:'reDraw',object:this, situation:'dragging'}  )
 	            
     } 
 	 

+ 44 - 33
src/custom/objects/tool/MeasuringTool.js

@@ -155,10 +155,13 @@ export class MeasuringTool extends THREE.EventDispatcher{
 			this.onAdd({measurement: measurement});
 		}
 		 
+         
+        viewer.addEventListener('camera_changed', this.update.bind(this),{importance:10})//优先级高于sprite
+         
+         
         if(Potree.config.measure.mulLabelHideFaraway ){
          
-            viewer.addEventListener('camera_changed', this.update.bind(this),{importance:10})//优先级高于sprite
-       
+            
             viewer.addEventListener("raycaster", this.beforeDraw.bind(this),{importance:10})   //before render
             viewer.addEventListener("render.begin", this.beforeDraw.bind(this),{importance:10}) //before render   
             viewer.addEventListener("render.begin2", this.beforeDraw.bind(this),{importance:10})  
@@ -226,42 +229,50 @@ export class MeasuringTool extends THREE.EventDispatcher{
                 
     }
     
-	update(e){
+	update(e){ 
+        if(viewer.inputHandler.measuring && Potree.settings.adsorption){
+            viewer.scene.measurements.forEach(measure=>{
+                measure.getPointsPos2d(e.viewport, true) 
+            })
+            
+        }
+        
         
         
+        if(Potree.config.measure.mulLabelHideFaraway){ 
         
-        if(e.changeInfo.projectionChanged || e.viewport.camera.type == 'PerspectiveCamera' && e.changeInfo.positionChanged){//for MulDistance
+            if(e.changeInfo.projectionChanged || e.viewport.camera.type == 'PerspectiveCamera' && e.changeInfo.positionChanged){//for MulDistance
           
-             
-            viewer.scene.measurements.forEach(measure=>{
-                if(measure.measureType != 'MulDistance' || (measure.isNew ? measure.points.length<4 : measure.points.length<3)) return
-                measure.getEdgeLabelVisi(e.viewport)
-                return  
-                
-                let lastIndex = measure.points.length - 1; 
-                for (let index = 0; index <= lastIndex; index++) {
-                    if(!measure.closed && index == lastIndex)continue 
-                    
-                    let nextIndex = (index + 1 > lastIndex) ? 0 : index + 1;
-                    let previousIndex = (index === 0) ? lastIndex : index - 1;
+                 
+                viewer.scene.measurements.forEach(measure=>{
+                    if(measure.measureType != 'MulDistance' || (measure.isNew ? measure.points.length<4 : measure.points.length<3)) return
+                    measure.getEdgeLabelVisi(e.viewport)
+                    return  
                     
-                    let point = measure.points[index];
-                    let nextPoint = measure.points[nextIndex];
-                    let previousPoint = measure.points[previousIndex];
-                    let point2d = new THREE.Vector2().copy(pos2ds[index]);
-                    let nextPoint2d = new THREE.Vector2().copy(pos2ds[nextIndex]);
-                    if(measure.showDistances || measure.labelText){ // edge labels
-                        let edgeLabel = measure.edgeLabels[index];
-                      
-                        if(edgeLabel.visible){
-                            measure.setEdgeLabelPos(edgeLabel, point, nextPoint  )
+                    let lastIndex = measure.points.length - 1; 
+                    for (let index = 0; index <= lastIndex; index++) {
+                        if(!measure.closed && index == lastIndex)continue 
+                        
+                        let nextIndex = (index + 1 > lastIndex) ? 0 : index + 1;
+                        let previousIndex = (index === 0) ? lastIndex : index - 1;
+                        
+                        let point = measure.points[index];
+                        let nextPoint = measure.points[nextIndex];
+                        let previousPoint = measure.points[previousIndex];
+                        let point2d = new THREE.Vector2().copy(pos2ds[index]);
+                        let nextPoint2d = new THREE.Vector2().copy(pos2ds[nextIndex]);
+                        if(measure.showDistances || measure.labelText){ // edge labels
+                            let edgeLabel = measure.edgeLabels[index];
+                          
+                            if(edgeLabel.visible){
+                                measure.setEdgeLabelPos(edgeLabel, point, nextPoint  )
+                            }  
                         }  
                     }  
-                }  
-            })
-            
-        }
-            
+                })
+                
+            }
+        }   
             
             
         return;
@@ -517,7 +528,7 @@ export class MeasuringTool extends THREE.EventDispatcher{
                 type : "CursorChange", action : "remove",  name:"polygon_AtWrongPlace"
             });
             
-            viewer.inputHandler.dispatchEvent({type:'isMeasuring',  v:false, cause:'stopInsertion'}  ) 
+            viewer.inputHandler.dispatchEvent({type:'measuring',  v:false, cause:'stopInsertion', situation:'adding', object:measure}  ) 
             
             
             //var isIntersectSelf = measure.atPlane && measure.closed && !measure.isRect && measure.point2dInfo && measure.intersectSelf(measure.point2dInfo.points2d.slice(0,measure.point2dInfo.points2d.length-1))//检测除了最后一个点的相交情况
@@ -646,7 +657,7 @@ export class MeasuringTool extends THREE.EventDispatcher{
         
         //点击第n下拥有n+1个marker, n>0
         
-        viewer.inputHandler.dispatchEvent({type: 'isMeasuring', v: true, cause:'startInsertion'})
+        viewer.inputHandler.dispatchEvent({type: 'measuring', v: true, cause:'startInsertion', situation:'adding', object:measure})
         
         this.viewer.addEventListener('global_click', click, {importance:10})//add  importance
             

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

@@ -183,7 +183,7 @@ export class ctrlPolygon extends THREE.Object3D {
         e.drag.object.isDragging = true 
         
         
-        I = e.intersect && (e.intersect.orthoIntersect || e.intersect.location)
+        I = e.intersect && (e.intersect.adsorption ? e.intersect.location : (e.intersect.orthoIntersect || e.intersect.location))
         
         //记录数据集
         

+ 7 - 9
src/custom/potree.shim.js

@@ -288,7 +288,7 @@ Utils.getMousePointCloudIntersection = function(viewport, mouse, pointer, camera
     let visiMap = new Map()
     let needsUpdate = false;
     
-    if(pickParams.isMeasuring || Potree.settings.displayMode == 'showPanos') { //(无深度图) 测量或全景模式提高精准度,因为漫游的
+    if(pickParams.measuring || Potree.settings.displayMode == 'showPanos') { //(无深度图) 测量或全景模式提高精准度,因为漫游的
         density = Potree.settings.pointDensity 
         Potree.settings.pointDensity = 'magnifier' 
         
@@ -352,7 +352,7 @@ Utils.getMousePointCloudIntersection = function(viewport, mouse, pointer, camera
     }
 
     //恢复
-    if(pickParams.isMeasuring || Potree.settings.displayMode == 'showPanos'){
+    if(pickParams.measuring || Potree.settings.displayMode == 'showPanos'){
         Potree.settings.pointDensity = density
         
         pointclouds.forEach(e=>{
@@ -445,12 +445,12 @@ Utils.mouseToRay = function(pointer, camera  ){
     return ray;
 }
 
-Utils.getPos2d = function(point, camera, dom, viewport){//获取一个三维坐标对应屏幕中的二维坐标
+Utils.getPos2d = function(point, viewport , dom  ){//获取一个三维坐标对应屏幕中的二维坐标
     var pos
-    if(math.closeTo(camera.position, point, 1e-5) ){ //和相机位置重合时显示会四处飘,看是要改成一直显示中间还是隐藏?
+    if(math.closeTo(viewport.camera.position, point, 1e-5) ){ //和相机位置重合时显示会四处飘,看是要改成一直显示中间还是隐藏?
         pos = new THREE.Vector3(0,0,1.5); //1.5是为了不可见
     }else{ 
-        pos = point.clone().project(camera)	//比之前hotspot的计算方式写得简单  project用于3转2(求法同shader); unproject用于2转3 :new r.Vector3(e.x, e.y, -1).unproject(this.camera);
+        pos = point.clone().project(viewport.camera)	//比之前hotspot的计算方式写得简单  project用于3转2(求法同shader); unproject用于2转3 :new r.Vector3(e.x, e.y, -1).unproject(this.camera);
     }
     
     
@@ -1254,15 +1254,13 @@ Potree.updateVisibility = function(pointclouds, camera, areaSize){
             return !!intersects */
             
              
-            return Potree.Utils.isIntersectBox(box, pcWorldInverse) 
+            return Potree.Utils.isIntersectBox(box, toPCObject) 
             
             
         }
 
         //改 总共两种box : 可见和不可见(都是并集)
- 
-    
-        
+  
 		let clipBoxes_in = pointcloud.material.clipBoxes_in;
 		let clipBoxes_out = pointcloud.material.clipBoxes_out;
         let bigClipInBox = pointcloud.material.bigClipInBox

+ 6 - 4
src/custom/settings.js

@@ -187,7 +187,9 @@ const config = {//配置参数   不可修改
        
         textColor: "#000000", //"#FFFFFF"
         
-        mulLabelHideFaraway : false // 多折线根据远近显示label
+        mulLabelHideFaraway : false ,// 多折线根据远近显示label
+        
+        adsorptMinDis : 30, //最小吸附距离(像素)
     },
     material:{//初始化
         pointSize: 0.1,  
@@ -441,8 +443,8 @@ let settings = {//设置   可修改
     useV4url:true, //v4的全景图等路径不一样 scene_view_data
     
     useRTskybox:true,  //直接使用rtEDL绘制到屏幕,当是全景模式时. 在降4倍时能给render节省1毫秒,gpu时间未测 
-    useRTPoint:true,    //直接使用rtEDL绘制到屏幕,当是点云模式时。可以大大节省gpu时间
-    pointEnableRT:false,//点云是否允许绘制到rtEDL。只在有需要时使用
+    useRTPoint:true,    //直接使用rtEDL绘制到屏幕,当是点云模式时。可以大大节省gpu时间。但有锯齿
+    pointEnableRT:false,//点云模式时是否绘制到rtEDL。如果不需要遮挡效果就不需绘制
     cloudSameMat:true,  //因为点云个数较多,就使用相同的材质,可见降低绘制速度(要保证所有点云的maxNodelevel一样,且要算出 material.spacing的平均值)
     
     showCompass : isTest,
@@ -450,7 +452,7 @@ let settings = {//设置   可修改
     // testCube : true,
     // moveToCenter:true, //针对数据集间隔很远的场景  dis>5000 容易抖动
     tiles3DMaxMemory: config.tiles3DMaxMemory,
-    
+    adsorption:false,//测量时吸附点 
    
 }
 

+ 1 - 1
src/custom/start.js

@@ -664,7 +664,7 @@ export function mergeEditStart(dom){
         //this.bound = new THREE.Box3(new THREE.Vector3(-1,-1,-1),new THREE.Vector3(1,1,1))
         
         viewer.transformationTool.setModeEnable(['translation','rotation'] )
-        viewer.ssaaRenderPass.sampleLevel = 1 //  sampleLevel为1 的话,ground就不会变黑
+        //viewer.ssaaRenderPass.sampleLevel = 1 //  sampleLevel为1 的话,ground就不会变黑
         
         viewer.inputHandler.fixSelection = true //不通过点击屏幕而切换transfrom选中状态
   

+ 2 - 21
src/custom/utils/browser.js

@@ -256,25 +256,7 @@ var browser = {
         return number
     },
 
-    urlHasValue: function(key, isGetValue) {
-        // debugger
-        // if (getValue) { //得到类似n=1 的 1
-        //     var b = window.location.href.substring(window.location.href.indexOf("?") + 1);
-        //     var a = b.indexOf('&' + t + "=");
-        //     if (a > -1) {
-        //         var s = b.substring(a + ('&' + t + "=").length);
-        //         s.indexOf("&") > -1 && (s = s.substring(0, s.indexOf("&")));
-        //         s.indexOf("#") > -1 && (s = s.substring(0, s.indexOf("#")));
-        //         return s;
-        //     } else return false;
-        // } else return window.location.search.match("&" + t + "|\\?" + t) != null; //window.location.href.substring(window.location.href.indexOf("?") + 1).indexOf('&' + t) > -1;
-
-        //const value = window.location.search.match("&" + t + "|\\?" + t)
-
-        if (key === "m" && window.__ProjectNum && window.__ProjectNum != "__ProjectNum__") {
-            return window.__ProjectNum
-        }
-
+    urlHasValue: function(key, isGetValue) {  
         let querys = window.location.search.substr(1).split("&")
         if (isGetValue) {
             for (let i = 0; i < querys.length; i++) {
@@ -284,8 +266,7 @@ var browser = {
                 }
             }
             return ""
-        } else {
-            //return window.location.search.match("&" + key + "|\\?" + key) != null  有bug
+        } else { 
             for (let i = 0; i < querys.length; i++) {
                 let keypair = querys[i].split("=")
                 if (keypair[0] == key) {

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

@@ -3491,10 +3491,10 @@ export class Viewer extends ViewerBase{
         const vrActive = this.renderer.xr.isPresenting;
         let SiteModel = viewer.modules.SiteModel 
         
-        
-        Potree.settings.useRTPoint = !(SiteModel.editing && SiteModel.selected && (SiteModel.selected.buildType == 'room' || SiteModel.selected.buildType == 'floor'))//空间模型的房间选中材质是需要depth的,这时候需要绘制两次点云
+   
+        let s = SiteModel.editing && SiteModel.selected && (SiteModel.selected.buildType == 'room' || SiteModel.selected.buildType == 'floor') //空间模型的房间选中材质是需要depth的,这时候需要绘制两次点云
          
-        Potree.settings.pointEnableRT = !this.screenshoting && (this.scene.measurements.length > 0 || !Potree.settings.useRTPoint )
+        Potree.settings.pointEnableRT = !this.screenshoting && (this.scene.measurements.length > 0 || s )
         
          
         if(vrActive){
@@ -3564,7 +3564,7 @@ export class Viewer extends ViewerBase{
         
         let screenshot = ()=>{ 
             let pose
-            console.log('screenshot',sid, Date.now())
+            //console.log('screenshot',sid, Date.now())
             useMap && (viewer.mapViewer.needRender = true)
             
             this.needRender = true
@@ -4173,6 +4173,7 @@ export class Viewer extends ViewerBase{
                 } */
                   
                 //出现过到达位置后测量线标签闪烁的情况
+                // 测量线截图 全景 最好能放大. 但要确保该位置放大后图片加载完有点困难
             }
             
         } else if (type == 'tag' || type == 'point') {

+ 136 - 85
src/navigation/InputHandlerNew.js

@@ -10,6 +10,9 @@ import {Utils} from "../utils.js";
 import Common from "../custom/utils/Common.js";
 import DepthBasicMaterial from '../custom/materials/DepthBasicMaterial.js'
 import browser from "../custom/utils/browser.js"; 
+import math from "../custom/utils/math.js"; 
+
+
 
 let {Buttons} = Potree.defines
 
@@ -27,6 +30,8 @@ export class InputHandler extends THREE.EventDispatcher {
 		this.interactiveObjects = new Set();
 		this.inputListeners = [];
 		this.blacklist = new Set();
+        
+
 
 		this.drag = null;
 		this.mouse = new THREE.Vector2(0, 0);
@@ -99,9 +104,25 @@ export class InputHandler extends THREE.EventDispatcher {
           
           
         {
-            this.addEventListener('isMeasuring',(e)=>{ 
-                //console.log('isMeasuring',e.v,e.cause)
-                this.isMeasuring = e.v 
+            this.measuring = [] //正在编辑的measure
+            //let mesureInfo = new THREE.EventDispatcher()
+            this.addEventListener('measuring',(e)=>{ 
+                //true优先级高于false, 正在添加时dropMarker也不会停止
+                
+                //Potree.Utils.updateVisible(mesureInfo, e.situation,  e.v, 0, e.v?'add':'cancel' )//借用该函数,使true优先级高于false,防止正在添加时dropMarker而停止
+                if(e.v){
+                    this.measuring.includes(e.object) || this.measuring.push(e.object)
+                }else{
+                    let index = this.measuring.indexOf(e.object)
+                    index > -1 && this.measuring.splice(index, 1)
+                }
+                 
+                if(this.measuring.length == 0 && this.measuring.length>0   ){
+                    this.viewer.viewports.forEach((viewport)=>{
+                        this.collectClosePoints(viewport, true )//forceUpdate
+                    }) 
+                } 
+                //console.log('measuring',e.v, e.cause, e.situation, this.measuring.length )
             }) 
         }
         
@@ -421,7 +442,7 @@ export class InputHandler extends THREE.EventDispatcher {
             //isTouch必须更新 否则是旧的 
             this.hoveredElements = this.getHoveredElements();
             let dontIntersect = false
-            this.intersect = this.getIntersect(viewport,null,null,dontIntersect) //更新intersect,避免在没有mousemove但flyToPano后intersect未更新。
+            this.intersect = this.getIntersect({viewport,  dontIntersect, clientX:e.clientX, clientY:e.clientY}) //更新intersect,避免在没有mousemove但flyToPano后intersect未更新。
             //this.intersect = this.getWholeIntersect()  
         }
         if(!viewport)return //why add this?
@@ -787,7 +808,7 @@ export class InputHandler extends THREE.EventDispatcher {
 
     ifBlockedByIntersect({pos3d, margin=0, cameraPos, pickWindowSize, pano, useDepthTex, viewport}={}){//某点是否被遮挡(不允许camera修改位置, 因为depthTex不好置换)
         viewport = viewport || this.hoverViewport || viewer.mainViewport
-        let intersect = this.getIntersect(viewport, true, pickWindowSize, null, null, useDepthTex, {pos3d, cameraPos, pano})
+        let intersect = this.getIntersect({viewport, onlyGetIntersect:true, pickWindowSize,  useDepthTex,  pos3d, cameraPos, pano })
         let cameraPos_ = (!cameraPos && pano) ? pano.position : (cameraPos||viewport.view.position)
         if(intersect && intersect.distance+margin <= pos3d.distanceTo(cameraPos_)){
             return intersect //被遮挡
@@ -795,10 +816,25 @@ export class InputHandler extends THREE.EventDispatcher {
         //点云模式,对没加载出的点云不准确。 尤其是需要修改相机位置时,因临时修改并不能使点云加载。
     }
 
+    collectClosePoints(viewport, forceUpdate){//获取吸附点
+        if(!Potree.settings.adsorption)return
+    
+        let point2ds = []
+        
+        //吸附测量线端点
+        
+        viewer.scene.measurements.forEach(e=>{
+            if(this.measuring.includes(e)) return//不吸附到正在拖拽的自身
+            point2ds.push(...e.getPointsPos2d(viewport, forceUpdate))
+        })
+         
+        return point2ds
+        
+        
+    }
 
-
-    getIntersect(viewport,   onlyGetIntersect, pickWindowSize, dontIntersect, usePointcloud, useDepthTex, prop={}){// usePointcloud:必须使用点云
-        let intersectPoint  
+    getIntersect({viewport, onlyGetIntersect, pickWindowSize, dontIntersect, usePointcloud, useDepthTex,  cameraPos,  point, pano, clientX, clientY}={}){// usePointcloud:必须使用点云
+        let intersect, intersectPoint, intersectOnModel, allElements 
         let camera = viewport.camera
         let raycaster 
         
@@ -806,27 +842,28 @@ export class InputHandler extends THREE.EventDispatcher {
 
         let getByDepthTex = ()=>{ 
             let intersect
-            if(prop.pos3d){
-                let cameraPos = prop.pano ? prop.pano.position : camera.position
-                let dir = new THREE.Vector3().subVectors(prop.pos3d, cameraPos).normalize(); 
+            if(point){
+                let cameraPos = pano ? pano.position : camera.position
+                let dir = new THREE.Vector3().subVectors(point, cameraPos).normalize(); 
                 intersect = {dir} 
             }else{
                 intersect = Utils.getIntersect(camera, [viewer.images360.cube], this.pointer, raycaster) 
             } 
-            intersectPoint = viewer.images360.depthSampler.sample(intersect, prop.pano, !!prop.pos3d)  //可能不准确, 因pano可能未加载depthTex
+            intersectPoint = viewer.images360.depthSampler.sample(intersect, pano, !!point)  //可能不准确, 因pano可能未加载depthTex
             if(intersectPoint && Potree.settings.depTexLocBindDataset){
-                intersectPoint.pointcloud = (prop.pano || viewer.images360.currentPano).pointcloud
+                intersectPoint.pointcloud = ( pano || viewer.images360.currentPano).pointcloud
                 //在全景模式下,虽然深度图上的点可能对应别的pointcloud,但因为是在当前全景图处得到的,所以即使将原本对应的点云移走,该点也不移动是有道理的。它可以永远跟着该全景图。
             }
         }
         
         let getByCloud = ()=>{
-            if(prop.pos3d){//指定了目标点,而非只是用pointer所在位置
-                prop.cameraPos && camera.position.copy(prop.cameraPos)
-                camera.lookAt(prop.pos3d)
+            let pointer, mouse
+            if(point){//指定了目标点,而非只是用pointer所在位置
+                cameraPos && camera.position.copy( cameraPos)
+                camera.lookAt(point)
                 camera.updateMatrixWorld()
-                prop.pointer = this.pointer.clone()
-                prop.mouse = this.mouse.clone()
+                pointer = this.pointer.clone()
+                mouse = this.mouse.clone()
                 this.pointer.set(0,0)   //画布中心
                 this.mouse.set(Math.round(viewport.resolution.x/2), Math.round(viewport.resolution.y/2))
             } 
@@ -838,77 +875,101 @@ export class InputHandler extends THREE.EventDispatcher {
                 camera, 
                 this.viewer, 
                 this.viewer.scene.pointclouds,
-                {pickClipped: true, isMeasuring: this.isMeasuring, pickWindowSize, cameraChanged: !!prop.pos3d }  
+                {pickClipped: true, measuring: this.measuring.length>0, pickWindowSize, cameraChanged: !!point }  
                 
             );
             //恢复
-            if(prop.pos3d){
+            if(point){
                 viewport.view.applyToCamera(camera)
-                this.pointer.copy(prop.pointer)
-                this.mouse.copy(prop.mouse)
+                this.pointer.copy(pointer)
+                this.mouse.copy(mouse)
             }  
         }
         
+        if(this.measuring.length && Potree.settings.adsorption ){//吸附
+            let points = this.collectClosePoints(viewport)
+            
+            let points2 = points.filter(e=>e.trueSide && e.inSight 
+               &&  math.closeTo(this.mouse, e.posInViewport, Potree.config.measure.adsorptMinDis)
+            )
+            
+            let disArr = points2.map(e=> e.pos.distanceToSquared(this.mouse)  )
+             
+            let min = points2.slice().sort((a,b)=>disArr[points.indexOf(a)] - disArr[points.indexOf(b)])
+            if(min[0]){
+                intersect = {
+                    //hoveredElement  
+                    location: min[0].pos3d,
+                    //point: {normal: allElements[0].face.normal },
+                    //normal 
+                    //distance 
+                    object: min[0].object,
+                    adsorption:true
+                }
+                console.log('找到吸附点',    min[0].pos3d, min[0].object.uuid)
+            } 
+        } 
         
         
-        let canUseDepthTex = (Potree.settings.displayMode == 'showPanos' || useDepthTex)
-            && viewer.images360.currentPano.pointcloud.hasDepthTex && viewport == viewer.mainViewport && !usePointcloud 
-        
-        
-        if(canUseDepthTex)getByDepthTex()
-        else getByCloud() 
-        /* if(canUseDepthTex && !this.isMeasuring){
-            getByDepthTex()
-        }else{
-            getByCloud() 
-            if(!intersectPoint && canUseDepthTex  ){  //若在测量,先尝试点云,再用全景 //后来发现有深度图的点云全景visibleNode为空,pick不到的
-                getByDepthTex()
-            }
-        }  */ 
-        
-        
-                   
-
-         
-        //console.log(viewport.name , intersectPoint &&  intersectPoint.location )
-        let intersect
-        let intersectOnModel, allElements
-       
-        
-        if(Potree.settings.intersectOnObjs && !dontIntersect){
-            if(prop.point){
-                raycaster = new THREE.Raycaster() 
-                var dir = new THREE.Vector3().subVectors(prop.point, camera.position).normalize()
-                raycaster.set(camera.position, dir) //var origin = new THREE.Vector3(pointer.x, pointer.y, -1).unproject(camera),
-            }  
+        if(!intersect){
             
+            let canUseDepthTex = (Potree.settings.displayMode == 'showPanos' || useDepthTex)
+                && viewer.images360.currentPano.pointcloud.hasDepthTex && viewport == viewer.mainViewport && !usePointcloud 
             
-            allElements = this.getHoveredElements(viewer.objs.children, true, raycaster)
             
+            if(canUseDepthTex)getByDepthTex()
+            else getByCloud() 
+            /* if(canUseDepthTex && this.measuring.length){
+                getByDepthTex()
+            }else{
+                getByCloud() 
+                if(!intersectPoint && canUseDepthTex  ){  //若在测量,先尝试点云,再用全景 //后来发现有深度图的点云全景visibleNode为空,pick不到的
+                    getByDepthTex()
+                }
+            }  */ 
+            
+            //console.log(viewport.name , intersectPoint &&  intersectPoint.location )
+        
+           
             
-            if(allElements[0]){
-                intersectOnModel = {//模拟点云的intersectPoint的结构写法
-                    hoveredElement : allElements[0] ,
-                    location: allElements[0].point,
-                    //point: {normal: allElements[0].face.normal },
-                    normal: allElements[0].face && allElements[0].face.normal,
-                    distance: allElements[0].distance,
-                    object: allElements[0].object
-                } 
+            if(Potree.settings.intersectOnObjs && !dontIntersect){
+                if(point){
+                    raycaster = new THREE.Raycaster() 
+                    var dir = new THREE.Vector3().subVectors(point, camera.position).normalize()
+                    raycaster.set(camera.position, dir) //var origin = new THREE.Vector3(pointer.x, pointer.y, -1).unproject(camera),
+                }  
+                
+                
+                allElements = this.getHoveredElements(viewer.objs.children, true, raycaster)
+                
+                
+                if(allElements[0]){
+                    intersectOnModel = {//模拟点云的intersectPoint的结构写法
+                        hoveredElement : allElements[0] ,
+                        location: allElements[0].point,
+                        //point: {normal: allElements[0].face.normal },
+                        normal: allElements[0].face && allElements[0].face.normal,
+                        distance: allElements[0].distance,
+                        object: allElements[0].object
+                    } 
+                }
+                
+                 
             }
             
-             
-        }
-        
-        if(intersectPoint && intersectOnModel){
-            if(intersectPoint.distance < intersectOnModel.distance){
-                intersect = intersectPoint
+            if(intersectPoint && intersectOnModel){
+                if(intersectPoint.distance < intersectOnModel.distance){
+                    intersect = intersectPoint
+                }else{
+                    intersect = intersectOnModel
+                } 
             }else{
-                intersect = intersectOnModel
+                intersect = intersectOnModel || intersectPoint
             } 
-        }else{
-            intersect = intersectOnModel || intersectPoint
-        }                
+                       
+        }
+         
+                       
           
         
         if(viewport.camera.type == 'OrthographicCamera'/*  == 'mapViewport' */){ 
@@ -999,21 +1060,11 @@ export class InputHandler extends THREE.EventDispatcher {
             let dontIntersect =  this.drag && viewport.alignment || isFlying || !Potree.settings.intersectWhenHover // flying 时可能卡顿
             //console.log('dontIntersectPointcloud',dontIntersectPointcloud)
             
-            /* if(e.onlyGetIntersect )   */intersect = this.getIntersect(viewport,  e.onlyGetIntersect, e.pickWindowSize, !!dontIntersect, e.whichPointcloud) //数据集多的时候卡顿
-            /* else  Potree.Common.intervalTool.isWaiting('getIntersect', ()=>{  
-                 this.intersect = this.getIntersect(viewport,  e.onlyGetIntersect, e.pickWindowSize, !!dontIntersect, e.whichPointcloud) //数据集多的时候卡顿
-            }, 156); */
-	                 
-            //console.log('intersect', intersect)
+            intersect = this.getIntersect(Object.assign({}, e, {viewport,  dontIntersect, clientX:e.clientX, clientY:e.clientY })) //数据集多的时候卡顿
+            
         } 
         
-        if(e.onlyGetIntersect){ 
-            /* if(Potree.settings.intersectOnObjs){
-                let hoveredElements = this.getHoveredElements() //应该不用发送mouseover事件吧
-                let intersect = this.getWholeIntersect(hoveredElements, intersectPoint)
-                return intersect
-            } 
-            return intersectPoint */
+        if(e.onlyGetIntersect){  
             return intersect
         }
         e.preventDefault();

+ 1 - 0
src/viewer/EDLRendererNew.js

@@ -285,6 +285,7 @@ export class EDLRenderer{//Eye-Dome Lighting 眼罩照明
                         shadowMaps:  lights.length > 0 ? [this.shadowMap] : null,
                         clipSpheres: viewer.scene.volumes.filter(v => (v instanceof SphereVolume)),
                         transparent: true,   //如果点云透明需要透明
+                        notAdditiveBlending: Potree.settings.notAdditiveBlending
                     });
                 } 
                 if(Potree.settings.intersectOnObjs){// model也要渲染到rtEDL