Jelajahi Sumber

测量线换样式 sprite升级

xzw 1 tahun lalu
induk
melakukan
0a60bd05c6

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

@@ -864,7 +864,7 @@ class LineMaterial extends ShaderMaterial {
                 this.uniforms.resolution.value.copy(viewport.resolution2)  
                 this.uniforms.devicePixelRatio.value = window.devicePixelRatio 
                 this.lineWidth = this.lineWidth_ //update
-                if(!this.useDepth || !e.viewport.camera.isPerspectiveCamera || !e.viewport)return
+                if(!this.realUseDepth || !e.viewport)return
                 let viewportOffset = viewport.offset || new THREE.Vector2() 
                 this.uniforms.viewportOffset.value.copy(viewportOffset)
                 
@@ -900,19 +900,17 @@ class LineMaterial extends ShaderMaterial {
             this.useDepth_ = value 
              
             if(value){
-                viewer.addEventListener("render.begin",  this.events.render)  
-                this.events.setSize( {viewport:viewer.mainViewport} )  
+                viewer.addEventListener("render.begin",  this.events.render)   
                 this.updateDepthParams() 
             }else{
-                viewer.removeEventListener("render.begin",  this.events.render)  
-                
+                viewer.removeEventListener("render.begin",  this.events.render)   
             }
         }
         
     } 
     
     
-    setRealDepth(useDepth){//确实使用到depthTex
+    setRealDepth(useDepth, viewport){//确实使用到depthTex
         if(this.realUseDepth != useDepth){
             if(useDepth ){
                 this.defines.useDepth = ''  
@@ -922,6 +920,8 @@ class LineMaterial extends ShaderMaterial {
             this.realUseDepth = useDepth
             if(this.autoDepthTest)this.depthWrite = this.depthTest = !useDepth  //如果useDepth = false,使用原始的depthTest
             this.needsUpdate = true
+            if(!viewport)viewport = viewer.mainViewport //暂时这么设置
+            useDepth && this.events.setSize({viewport})
         }
     }
     
@@ -936,7 +936,7 @@ class LineMaterial extends ShaderMaterial {
         let hasDepth = this.useDepth && camera.isPerspectiveCamera && 
                 (Potree.settings.pointEnableRT || Potree.settings.displayMode == 'showPanos' || viewer.useEDL)
         
-        this.setRealDepth(hasDepth)
+        this.setRealDepth(hasDepth, viewport)
         
         if(hasDepth){
             this.uniforms.depthTexture.value = viewer.getPRenderer().getRtEDL(viewport).depthTexture   //其实只赋值一次就行

TEMPAT SAMPAH
resources/textures/pic_point32.png


TEMPAT SAMPAH
resources/textures/pic_point_s32.png


+ 12 - 28
src/custom/materials/DepthBasicMaterial.js

@@ -23,7 +23,7 @@ export default class DepthBasicMaterial extends THREE.ShaderMaterial{
             occlusionDistance :     { type: 'f', 	value:  o.occlusionDistance || 1  }, //变为backColor距离
             maxClipFactor :  { type: 'f', 	value: o.maxClipFactor || 1 },  //0-1 
             maxOcclusionFactor :  { type: 'f', 	value: o.maxOcclusionFactor || 1 },  //0-1
-
+            mapScale:  { type: 'f', 	value:  o.mapScale || 1 },  //0-1
 		}  
      
         super({ 
@@ -39,26 +39,13 @@ export default class DepthBasicMaterial extends THREE.ShaderMaterial{
         
         
         this.events = {
-            setSize:(e)=>{//如果出现横条状的异常,往往是viewportOffset出错  //地图不需要
-                if(!this.useDepth || !e.viewport.camera.isPerspectiveCamera || !e.viewport)return
+            setSize:(e)=>{//如果出现横条状的异常,往往是viewportOffset出错  //地图不需要 
+                if(!this.realUseDepth || !e.viewport)return
                 let viewport = e.viewport
                 let viewportOffset = viewport.offset || new THREE.Vector2() 
                 this.uniforms.resolution.value.copy(viewport.resolution2)  //2023.6.12突然发现ratio>1的用resolution不对,得用2才对。但是之前明明记得不是这样
                 this.uniforms.viewportOffset.value.copy(viewportOffset)
-                
-                
-                /* let dt = this.uniforms.depthTexture.value
-                if(window.logDep != 1000 && dt ){ 
-                    window.logDep = (window.logDep || 0) + 1
-                    
-                    
-                    console.log(' DepthParams', [ viewport.resolution.x, viewport.resolution.y], 
-                        [dt.image.width, dt.image.height] ,
-                        this.uniforms.nearPlane.value, this.uniforms.farPlane.value
-                    )
-                    
-                } */
-                
+                  
             },
             render:(e)=>{//before render  如果有大于两个viewport的话,不同viewport用不同的depthTex
                 this.updateDepthParams(e)
@@ -105,10 +92,7 @@ export default class DepthBasicMaterial extends THREE.ShaderMaterial{
             if(value){
                 viewer.addEventListener("render.begin",  this.events.render) 
                 //viewer.addEventListener('camera_changed', this.events.cameraChange) 
-                viewer.addEventListener('resize', this.events.setSize) 
-
-                
-                this.events.setSize( {viewport:viewer.mainViewport} )  
+                viewer.addEventListener('resize', this.events.setSize)  
                 this.updateDepthParams() 
             }else{
                 viewer.removeEventListener("render.begin",  this.events.render)  
@@ -119,8 +103,8 @@ export default class DepthBasicMaterial extends THREE.ShaderMaterial{
     } 
     
     
-    setRealDepth(useDepth){//确实使用到depthTex
-        if(this.realUseDepth != useDepth){
+    setRealDepth(useDepth, viewport){//确实使用到depthTex
+        if(this.realUseDepth != useDepth){ 
             if(useDepth ){
                 this.defines.useDepth = ''  
             }else{
@@ -129,6 +113,8 @@ export default class DepthBasicMaterial extends THREE.ShaderMaterial{
             this.realUseDepth = useDepth
             if(this.autoDepthTest)this.depthWrite = this.depthTest = !useDepth  //如果useDepth = false,使用原始的depthTest
             this.needsUpdate = true
+            if(!viewport)viewport = viewer.mainViewport //暂时这么设置
+            useDepth && this.events.setSize({viewport})
         }
     }
     
@@ -184,15 +170,13 @@ export default class DepthBasicMaterial extends THREE.ShaderMaterial{
         
         let hasDepth = this.useDepth && camera.isPerspectiveCamera && 
                 (Potree.settings.pointEnableRT || Potree.settings.displayMode == 'showPanos' || viewer.useEDL)
-        
-        this.setRealDepth(hasDepth)
+         
+        this.setRealDepth(hasDepth, viewport)
         
         if(hasDepth){
             this.uniforms.depthTexture.value = viewer.getPRenderer().getRtEDL(viewport).depthTexture   //其实只赋值一次就行
             this.uniforms.nearPlane.value = camera.near;
-            this.uniforms.farPlane.value = camera.far;
-            
-            
+            this.uniforms.farPlane.value = camera.far; 
         }
         //this.uniforms.uUseOrthographicCamera.value = !camera.isPerspectiveCamera
     }

+ 1 - 1
src/custom/modules/panoEdit/panoEditor.js

@@ -1061,7 +1061,7 @@ class PanoEditor extends THREE.EventDispatcher{
                  } 
              }
              
-             circle.update() //update sprite Matrix
+             circle.waitUpdate() //update sprite Matrix
              
         }
         

+ 4 - 4
src/custom/modules/panos/Panorama.js

@@ -296,8 +296,8 @@ class Panorama extends THREE.EventDispatcher{
             //marker.lookAt(marker.up) 
             marker.scale.set(2,2,2)  */
             
-        let marker = new Sprite({mat:this.getMarkerMat(), dontFixOrient:true })
-            marker.scale.set(0.4,0.4,0.4)
+        let marker = new THREE.Mesh(planeGeo, this.getMarkerMat() ) //new Sprite({mat:this.getMarkerMat(), dontFixOrient:true })
+            marker.scale.set(2,2,2)//marker.scale.set(0.4,0.4,0.4)
             marker.name = 'marker_'+this.id
             marker.up.set(0,0,1)
             
@@ -565,8 +565,8 @@ class Panorama extends THREE.EventDispatcher{
         this.marker.add(this.label2)
         
         //this.floorPosition && this.label2.position.copy(this.floorPosition)
-        //let s = 0.25
-        //this.label2.scale.set(s,s,s)
+        let s = 0.2 
+        this.label2.scale.set(s,s,s)
         Potree.Utils.updateVisible(this.label2, 'notDisplay', false)
         Potree.Utils.updateVisible(this.label2, 'panoVisi', this.visible)
         

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

@@ -6,7 +6,7 @@ import Viewport from '../viewer/Viewport.js'
 import {ExtendView} from "../../viewer/ExtendView.js"; 
 const texLoader = new THREE.TextureLoader() 
 const circleGeo = new THREE.CircleGeometry(1.45,100);
-const sphereGeo = new THREE.SphereBufferGeometry(0.015,8,8);
+const sphereGeo = new THREE.SphereBufferGeometry(0.012,8,8);
  
  
 const magDisMin = 1;//相机离目标位置的距离的分界线,当离得远时要缩小fov以使看到的视野固定(望远镜效果)
@@ -124,12 +124,12 @@ export default class Magnifier extends THREE.Object3D {//放大镜or望远镜
         this.targetPoint.add(new THREE.Mesh(sphereGeo, new THREE.MeshBasicMaterial({ 
             color:"#ff0000",
             transparent:true,
-            opacity:0.6,  
+            opacity:0.7,  
         })))
         this.targetPoint.add(new THREE.Mesh(sphereGeo, new THREE.MeshBasicMaterial({ 
             color:"#ff0000",
             transparent:true,
-            opacity:0.4, 
+            opacity:0.3, 
             depthTest:false  //被遮挡层
         })))
         

+ 161 - 25
src/custom/objects/Sprite.js

@@ -5,7 +5,7 @@ import math from "../utils/math.js";
 const geo = new THREE.PlaneBufferGeometry(1,1)
 export default class Sprite extends THREE.Mesh{
     
-    constructor(options){  
+    constructor(options={}){  
         super(geo, options.mat || new DepthBasicMaterial(options))/* ({map:options.map, useDepth:options.useDepth})) */
          
         this.root = options.root || this;
@@ -13,58 +13,87 @@ export default class Sprite extends THREE.Mesh{
         this.pickOrder = options.pickOrder || 0
         this.sizeInfo = options.sizeInfo
         this.dontFixOrient = options.dontFixOrient
+        this.options = options 
+        this.position.y = options.disToLine || 0 //离线距离
         
         this.root.matrixAutoUpdate = false;
         this.matrixMap = new Map()
+        this.visiMap = new Map()
         this.name = options.name || 'sprite'
         this.useViewport = null
         this.viewports = options.viewports//指定更新的viewports
         this.visible_ = true
         
         
-        let update = (e)=>{
-            //this.update(e)
-            this.matrixMap.clear()    //this.needsUpdate = true
+        let clear = (e)=>{
+            this.matrixMap.clear()//清空后在所有viewport上都必须更新才能渲染    //this.needsUpdate = true
         }
-        viewer.mapViewer && viewer.mapViewer.addEventListener("camera_changed",  update) 
-        viewer.addEventListener("camera_changed",  update) 
+        viewer.mapViewer && viewer.mapViewer.addEventListener("camera_changed",  clear) 
+        viewer.addEventListener("camera_changed",  clear) 
         /* if(viewer.viewports.length == 1){//直接更新。如果有多个不在这更新,在"render.begin"
             this.update(e)
         } */
          
         
         let applyMatrix = (e)=>{
-            /* if(this.needsUpdate) this.update(e)
-            else  */this.applyMatrix(e)
+            this.applyMatrix(e)
         }
         viewer.addEventListener("raycaster", applyMatrix)        //before render
-        viewer.addEventListener("render.begin", applyMatrix) //before render  //magnifier时要禁止吗
+        viewer.addEventListener("render.begin", applyMatrix) //before render   
+        viewer.addEventListener("render.begin2", applyMatrix)  
+        viewer.addEventListener("cameraSetLayers", applyMatrix) 
+            
             
         this.addEventListener('dispose', ()=>{
-            viewer.mapViewer && viewer.mapViewer.removeEventListener("camera_changed",  update) 
-            viewer.removeEventListener("camera_changed",  update) 
+            viewer.mapViewer && viewer.mapViewer.removeEventListener("camera_changed",  clear) 
+            viewer.removeEventListener("camera_changed",  clear) 
             viewer.removeEventListener("raycaster", applyMatrix)        //before render
             viewer.removeEventListener("render.begin", applyMatrix)
-             
+            viewer.removeEventListener("render.begin2", applyMatrix)
             this.dispose()
         })
          
     }
     
     set visible(v){
+        let oldV = this.visible_
         this.visible_ = v  
-        if(v){
-            this.update()
+        if(v && !oldV){ 
+            this.matrixMap && this.matrixMap.clear() //this.update() //update内有unableCompute会无限回调
         }
     }
     get visible(){
         return this.visible_ 
     }
     
-    realVisible(){
+     
+    realVisible(viewport, interactables/* , raycaster */){
+        if(interactables){
+            if(!interactables.some((object)=>{//interactables中是否能找到this
+                let finded
+                object.traverse((object)=>{
+                    if(object == this){
+                        finded = true
+                        return {stopContinue:true}
+                    }
+                })
+                return finded
+            }))return
+        }
+        
+        /* if(interactables && viewport.name == 'mapViewport'){
+            console.log(this)
+        } */
+        if(!(/* raycaster ||  */viewport.camera).layers.test(this.layers)){//如地图上一般不可见测量线
+            return false
+        }
+        
+        if(!this.visible && this.unvisibleReasons && this.unvisibleReasons.some(e=>e.reason != 'unableCompute')){
+            return false
+        }
         let v = true 
-        let parent = this 
-        let lastParent
+        let parent = this.parent 
+        let lastParent = this
         while(parent){
             if(parent.visible === false){
                 v = false
@@ -90,16 +119,24 @@ export default class Sprite extends THREE.Mesh{
         return v;
     }
     
-    update(e){
-        if(!e){
+    waitUpdate(){
+        this.matrixMap.clear()//清空后在所有viewport上都必须更新才能渲染 
+        //viewer.dispatchEvent('content_changed')
+    }
+    
+    
+    
+    
+    update(e={}){ 
+        if(!e.viewport){
             let viewports = this.viewports || viewer.viewports
-            if(!viewports)return
+            if(!viewports)return 
             viewports.forEach(view=>{
                 this.update({viewport:view}) 
             })
             return;
         }
-        if(!this.root || ! this.realVisible() /* this.visible */ )return
+        if(!this.root || ! this.realVisible(e.viewport, e.interactables) /* this.visible */ )return
         if(this.viewports && !this.viewports.includes(e.viewport) )return
         if(e.viewport.name == 'magnifier')return
         
@@ -107,8 +144,99 @@ export default class Sprite extends THREE.Mesh{
         //rotation
         
         if(!this.dontFixOrient){        //orthoCamera一般要加dontFixOrient  
+            let orient2dAngle    
+    
+            if(this.root.lineDir){  
+                this.root.updateMatrix();//先更新,getWorldPosition才能得到正确的
+                this.root.updateMatrixWorld(true)
+                let center = this.root.getWorldPosition(new THREE.Vector3())
+                //由于两个端点容易在屏幕外,所以使用center和center加dir
+                let setVisi = (state)=>{
+                    this.visiMap.set(e.viewport, state)
+                    Potree.Utils.updateVisible(this, 'unableCompute', !!state)
+                }
+                
+                
+                let r1 = Potree.Utils.getPos2d(center, camera, viewer.renderArea, e.viewport); 
+                if(!r1.trueSide)return  setVisi(false);// 但这句会使realVisible为false从而无法更新//console.error('!r1.trueSide') //中心点如果在背面直接不渲染了
+                    
+                let r2, point2
+                
+                let p2State = '', len=1,  p2StateHistory = []
+                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);  
+                    if(!r2.trueSide){ //很少遇到点2在背面的
+                        if(!p2StateHistory.includes('tooLong-reverse')){
+                            p2State = 'tooLong-reverse'  //先尝试反向
+                            len = -len
+                        }else{
+                            p2State = 'tooLong'
+                            len = len / 2
+                        }
+                    }else{
+                        let dis = r2.pos.distanceTo(r1.pos)
+                        if(math.closeTo(dis,0)){
+                            //console.log('dis == 0') 
+                            setVisi(false)
+                            return
+                            break
+                        } 
+                        if(dis<10 && !p2StateHistory.includes('tooLong')){//和r1的屏幕距离太近,要加长,否则精度过低
+                            p2State = 'tooShort'
+                            len = 100/dis * len  
+                        }else{ 
+                            p2State = 'got'; break;
+                        }
+                    } 
+                    p2StateHistory.push(p2State) 
+                }
+                //console.log(p2StateHistory,len)
+                
+                if(!r2.trueSide){
+                    return  setVisi(false)//, console.log('  !r2.trueSide', )
+                }
+                 
+                
+                
+                let orient2dInfo = {} 
+                let p1 = r1.pos,  p2 = r2.pos 
+                if(p2StateHistory.filter(e=>e == 'tooLong-reverse').length%2 == 1){//反,for marker
+                    p2 = r1.pos,  p1 = r2.pos
+                }
+                
+                
+                let vec = new THREE.Vector2().subVectors(p1,p2);
+                orient2dAngle = -vec.angle() //根据测量线在屏幕上的角度在旋转label,使之和屏幕上的二维线平行。
+                
+                let y = Math.abs(this.position.y)
+                let facePlane = this.root.measure && this.root.measure.facePlane 
+                let eyeDir = new THREE.Vector3().subVectors(center,camera.position)
+                let clockWise = facePlane && facePlane.normal.dot(eyeDir/* e.viewport.view.direction */) < 0
+                if(p1.x < p2.x){ 
+                    orient2dAngle += Math.PI  //避免字是倒着的情况。(使字一直在线的下方)
+                    clockWise != void 0 && (this.position.y = clockWise ? y : -y)  
+                }else{
+                    clockWise != void 0 && (this.position.y = clockWise ? -y : y) //使area类型的edgeLabel都在外侧
+                }
+                  
+                //this.parent.text && console.log(this.parent.text, clockWise, this.position.y, e.viewport.name   /* THREE.Math.radToDeg(angle), p1.x < p2.x */   )
+                 
+            
+                setVisi(true)
+              
+            } 
+                
+                 
             let parentQua = this.root.parent.getWorldQuaternion(new THREE.Quaternion)
             this.root.quaternion.multiplyQuaternions(parentQua.invert(),camera.quaternion)    //乘上parentQua.invert()是为了中和掉父结点的qua,使只剩下camera.quaternion
+        
+            if(orient2dAngle){ 
+                let qua = new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(0,0,1),  orient2dAngle) 
+                this.root.quaternion.multiply(qua) 
+            }
+        
         }
         
         //scale
@@ -142,20 +270,28 @@ export default class Sprite extends THREE.Mesh{
         }
         this.root.updateMatrix();
         this.root.updateMatrixWorld(true)
+        //console.log(this.root.text, this.root.matrix.elements)
         this.matrixMap.set(e.viewport, this.root.matrix.clone())
-        
+        this.needsUpdate = false
         this.useViewport = e.viewport
          
     }
     
     applyMatrix(e){
         if(!e)e = {viewport:viewer.mainViewport}//随便写一个viewport
+        
+        let visi = this.visiMap.get(e.viewport) //还原可见性
+        Potree.Utils.updateVisible(this, 'unableCompute', visi == false ? false : true );  
+        /* if(e.viewport.name == 'mapViewport' && visi && this.visiMap.get(viewer.mainViewport) == false){
+            console.log(1)
+        } */
+        
         if(e.viewport.name == 'magnifier')return
         if(this.viewports && !this.viewports.includes(e.viewport) )return
-        if( !this.root || !this.realVisible()  )return
-        
+        if( !this.root || !this.realVisible(e.viewport, e.interactables)  )return
+         
         var matrix = this.matrixMap.get(e.viewport);
-          
+           
         if(!matrix){
             this.update(e)
             matrix = this.matrixMap.get(e.viewport);

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

@@ -75,10 +75,10 @@ export class TextSprite extends THREE.Object3D{
 	}
     setPos(pos){
         this.position.copy(pos)
-        this.sprite.update()
+        this.sprite.waitUpdate() 
     }
     update(){
-        this.sprite.update()
+        this.sprite.waitUpdate()
     }
     setVisible(v){ 
         Potree.Utils.updateVisible(this, 'setVisible', v)

+ 173 - 119
src/custom/objects/tool/Measure.js

@@ -8,7 +8,7 @@ import math from "../../utils/math.js";
 import DepthBasicMaterial from "../../materials/DepthBasicMaterial.js";
 import Sprite from '../Sprite.js'
 import {config} from '../../settings.js'
-
+import browser from "../../utils/browser.js";
 import {ctrlPolygon} from './ctrlPolygon.js'
 
  
@@ -22,18 +22,24 @@ var markerMats;
 var lineMats;  
 var planeMats 
  
+const textSizeRatio = math.linearClamp(window.innerWidth * window.innerHeight , 360*720,   1920*1080, 0.75, 1)  //pc字显示大一些
+ 
 const lineDepthInfo = {
     clipDistance : 4,//消失距离
     occlusionDistance: 1,//变为backColor距离 
 }
  
- 
+const markerMapShrink = browser.isMobile() ? 0.4 : 0.8  //触屏需要更大的热区
 
 const markerSizeInfo = {
-    minSize : 25 ,  maxSize : 65,   nearBound : 0.2, farBound : 4,
-}
+    width2d : 18 / markerMapShrink  ,   nearBound : 1.5, farBound : 15,
+}  
+/* const markerSizeInfo = {
+    minSize : 10 ,   maxSize : 15 ,   nearBound : 1.5, farBound : 15,
+} */
+
 const labelSizeInfo = {width2d:200}
-const mainLabelProp = { 
+/* 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, 
@@ -45,14 +51,44 @@ const mainLabelProp = {
     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}, 
+    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, 
+    borderRadius : 12, margin:{x:20,y:4},
+    renderOrder : 5, pickOrder:5, 
+    disToLine:-0.15,
+    
+    useDepth : true , 
+    // 2023.10 尽量不让数字被挡住
+    clipDistance : 10,//消失距离
+    occlusionDistance: 10,//变为backColor距离 
+    maxOcclusionFactor:0.3,
+    maxClipFactor:0.8
+    
 }
 const subLabelProp = { 
+    backgroundColor: {r: 255, g: 255, b: 255, a:0},
+    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,  
+    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}
@@ -230,18 +266,26 @@ export class Measure extends ctrlPolygon{
          
          
         let setEdgeLabel = (label,p1,p2,distance)=>{//设置label位置和字
-            let center = new THREE.Vector3().addVectors(p1,p2).multiplyScalar(0.5);  
-            label.setPos(center) 
+            this.setEdgeLabelPos(label,p1,p2) 
             distance = distance == void 0 ? p1.distanceTo(p2) : distance; 
             //var text = viewer.unitConvert.convert(distance, 'distance', Potree.settings.precision, this.unitSystem, 1 , true)//distance要传0.1 这个factor
             var text = viewer.unitConvert.convert(distance, 'distance',  Potree.settings.precision , this.unitSystem, 0.01 , true  )//distance要传0.1 这个factor
-                     
-            
             label.setText(text)
             return distance
         }
          
          
+        /* let setEdgeLabel = (label,p1,p2,distance)=>{//设置label位置和字
+            this.setEdgeLabelPos(label,p1,p2)
+ 
+            distance = distance == void 0 ? p1.distanceTo(p2) : distance; 
+            var text = this.labelText || viewer.unitConvert.convert(distance, 'distance',  Potree.settings.precision , this.unitSystem, 0.001 , true, true)//distance要传0.1 这个factor
+            label.setText(text)
+          
+        } */
+         
+         
+         
         let lastIndex = this.points.length - 1; 
         for (let index = 0; index <= lastIndex; index++) {
             
@@ -260,6 +304,7 @@ export class Measure extends ctrlPolygon{
                 edgeLabel.shouldVisi = (index < lastIndex || this.isRect || this.closed && !this.isNew ) && distance>0 
                 /* this.closed || */edgeLabel.setVisible(edgeLabel.shouldVisi)  
                 if(edgeLabel.visible){
+                    edgeLabel.lineDir = new THREE.Vector3().subVectors(point,nextPoint).normalize() //[point,nextPoint]
                     setEdgeLabel(edgeLabel,point,nextPoint,distance)
                 }  
             }
@@ -307,13 +352,85 @@ export class Measure extends ctrlPolygon{
                 this.areaLabel.setText(msg);
                 this.areaLabel.setVisible(true)
             //}  
-        } 
-             
-         
-		
+        }  
 	};
+    
+     
+    
+
+    setEdgeLabelPos(label,p1,p2){ //调整label的位置,使倾斜后看起来在线的中心,而不要挡住端点
+        let center = new THREE.Vector3().addVectors(p1,p2).multiplyScalar(0.5);  
+        return label.setPos(center) 
+        
+        
+        
+        if(label.lineDir && label.lineDir.length() > 0){
+            if(viewer.mainViewport.camera.type == 'OrthographicCamera'){
+                label.setPos(center) 
+            }else{
+                //根据视线和线的夹角(后又加入相机和两个端点距离差)来决定标签偏移位置。+
+                let eyePos = viewer.mainViewport.camera.position;
+                let dir = viewer.mainViewport.view.direction //new THREE.Vector3().subVectors(center,eyePos).normalize()
+                 
+                /*let centerDir = new THREE.Vector3().subVectors(center,eyePos).normalize()
+                if(centerDir.dot(dir)<0){//中点在相机后方,就不设置
+                    label.setPos(center)
+                    return
+                } */
+                let cos = dir.dot(label.lineDir) 
+                let nearPoint = cos > 0 ? p2 : p1 //近端点。 
+                let far = cos > 0 ? p1 : p2 //远端点。 
+                let nearPointDir = new THREE.Vector3().subVectors(nearPoint,eyePos)//.normalize()
+                //使label在中点和近端点中变化, 近端点可能到了相机后方,需要投影到相机所在平面上
+                if(nearPointDir.dot(dir)<0){//近端点到了相机后方,前移。 
+                //let hfov = cameraLight.getHFOVForCamera(viewer.mainViewport.camera , true  ); //暂且只看水平fov 
+                //if(nearPointDir.dot(dir)<Math.cos(hfov/2)){//近端点在镜头外,前移。    --但是这个就得把点转化成在镜头边缘而非左右两边(camDirPlane上)
+                    let ray = new THREE.Raycaster()
+                    ray.set(nearPoint, cos>0?label.lineDir:label.lineDir.clone().negate())
+                    let camDirPlane = new THREE.Plane().setFromNormalAndCoplanarPoint(dir,  eyePos) 
+                    nearPoint = ray.ray.intersectPlane(camDirPlane, new THREE.Vector3()) 
+                    if(!nearPoint){//线是垂直的,视线是水平的时候 
+                        return label.setPos(center) 
+                    } 
+                } 
+                  
+                  
+                //防止离远了之后也偏移很多,但远了之后相机到端点vec和到中点的vec的夹角接近,不需要怎么偏移的。  
+                let dis1 = nearPoint.distanceToSquared(eyePos)
+                let dis2 = far.distanceToSquared(eyePos)
+                let diff = Math.abs(dis1/dis2)
+                diff<1 && (diff = 1/diff)
+                diff = math.linearClamp(diff,0, 30,    0,1 ) 
+                  
+                  
+                  
+                let efficiency = 0.7; // 0-1  数值越高,r越容易接近1或-1,label越容易在倾斜后靠近近端点。 
+                //let r = 0.5*efficiency*cos + 0.5  
+                let r = 0.5*efficiency*diff*cos + 0.5
+                r = THREE.Math.clamp(r,0.1,0.9)
+                
+                //视线越接近线的方向,标签应该越往近端点偏移,防止看起来几乎在远端。
+                if(cos > 0){
+                    center = p1.clone().multiplyScalar(1-r).add(nearPoint.clone().multiplyScalar(r)); //label在线上滑动,使尽量保持在视觉中心
+                }else{
+                    center = nearPoint.clone().multiplyScalar(1-r).add(p2.clone().multiplyScalar(r)); //label在线上滑动,使尽量保持在视觉中心
+                }
+                
+                label.setPos(center)
+            }
+             
+            
+            //归零
+            //this.orient2dInfo = null 
+            //this.markers.forEach(e=>e.needsUpdate=true)
+        }else{
+            
+            label.setPos(center)   
+        }
+     
+            
+    }
 
-  
       
 	addMarker (o={}) {
          
@@ -327,7 +444,7 @@ export class Measure extends ctrlPolygon{
         marker.addEventListener('drop',(e)=>{
             viewer.inputHandler.dispatchEvent({type: 'isMeasuring',  v:false, cause:'stopDragging'}  )
         })
-         
+        //marker.measure = this 
         let edge
 		{ // edges 
             edge = LineDraw.createFatLine( [ ],{mat:this.getLineMat('edgeDefault')} ) 
@@ -666,6 +783,7 @@ export class Measure extends ctrlPolygon{
             })
         }
         edgeLabel.visible = false
+        edgeLabel.measure = this
         edgeLabel.sprite.material.depthTestWhenPick = true
         Potree.Utils.setObjectLayers(edgeLabel, 'measure' )
         this.add(edgeLabel)
@@ -673,20 +791,9 @@ export class Measure extends ctrlPolygon{
     }
     
     createAreaLabel(){ 
-        /* const areaLabel = new Label({
-            className:'measure_area', 
-            
-        })
-        areaLabel.elem.on('mouseover',()=>{
-            this.setSelected(true, 'areaLabel')
-        })
-        areaLabel.elem.on('mouseout',()=>{
-            this.setSelected(false, 'areaLabel')
-        }) */
-        
-        
+    
         const areaLabel = new TextSprite(
-            $.extend(mainLabelProp,{sizeInfo: labelSizeInfo, name:'areaLabel_'} )
+            $.extend({},mainLabelProp,{sizeInfo: labelSizeInfo, name:'areaLabel_', disToLine:0, fontsize:16*textSizeRatio} )
         )
         
         areaLabel.addEventListener('mouseover',()=>{
@@ -709,22 +816,27 @@ export class Measure extends ctrlPolygon{
     
     getMarkerMaterial(type) { 
         if(!markerMats){
+            
             markerMats = {  
                 default:    new DepthBasicMaterial($.extend({},lineDepthInfo,{ 
                     transparent: !0,
                     opacity: 1,
                     map: texLoader.load(Potree.resourcePath+'/textures/pic_point_s32.png' ), 
-                    useDepth:true 
+                    useDepth:true ,
+                    mapScale: markerMapShrink
                 })),
                 select:    new THREE.MeshBasicMaterial({  
                     transparent: !0,
                     opacity: 1,
                     depthTest:false,
-                    map: texLoader.load(Potree.resourcePath+'/textures/pic_point32.png'/* , null, null, { antialias: false } */), 
-                     
+                    map: texLoader.load(Potree.resourcePath+'/textures/pic_point32.png'/*   , null, null, { antialias: false } */), 
                 }),   
             }
             Measure.markerMats = markerMats
+             
+            markerMats.select.map.repeat.set(1/markerMapShrink,1/markerMapShrink) 
+            markerMats.select.map.offset.set((markerMapShrink-1)/2/markerMapShrink,  (markerMapShrink-1)/2/markerMapShrink)
+            //markerMats.select.map.offset.set( -1.1 , -1.1 )
         }
         return markerMats[type]
         
@@ -761,7 +873,7 @@ export class Measure extends ctrlPolygon{
                     dashSize: 0.1, 
                     gapSize: 0.02,
                     dashed: true,
-                    lineWidth: config.measure.lineWidth  
+                    lineWidth: config.measure.lineWidth/2  
                 }))
                     
             }
@@ -942,97 +1054,34 @@ export class Measure extends ctrlPolygon{
         }
         viewer.inputHandler.dispatchEvent( {type:'isMeasuring', v:true, cause:'reDraw'}  )
 	            
-    }
-    
-
-
-	/* get showCoordinates () {
-		return this._showCoordinates;
-	}
-
-	set showCoordinates (value) {
-		this._showCoordinates = value;
-		this.update();
-	}
-
-	get showAngles () {
-		return this._showAngles;
-	}
-
-	set showAngles (value) {
-		this._showAngles = value;
-		this.update();
-	}
-
-	get showCircle () {
-		return this._showCircle;
-	}
-
-	set showCircle (value) {
-		this._showCircle = value;
-		this.update();
-	}
-
-	get showAzimuth(){
-		return this._showAzimuth;
-	}
-
-	set showAzimuth(value){
-		this._showAzimuth = value;
-		this.update();
-	}
-
-	get showEdges () {
-		return this._showEdges;
-	}
-
-	set showEdges (value) {
-		this._showEdges = value;
-		this.update();
-	}
-
-	get showHeight () {
-		return this._showHeight;
-	}
-
-	set showHeight (value) {
-		this._showHeight = value;
-		this.update();
-	}
-
-	get showArea () {
-		return this._showArea;
-	}
-
-	set showArea (value) {
-		this._showArea = value;
-		this.update();
-	}
-
-	get closed () {
-		return this._closed;
-	}
-
-	set closed (value) {
-		this._closed = value;
-		this.update();
-	}
-
-	get showDistances () {
-		return this._showDistances;
-	}
-
-	set showDistances (value) {
-		this._showDistances = value;
-		this.update();
-	} */
+    } 
+	 
+ 
 
 }
 
 
- 
+function setLabelHightState(label, state){ 
+    if(state){  
+        let color = new THREE.Color(Potree.config.measure.highlight.color) 
+        //label.sprite.material.opacity = config.measure.highlight.opacity
+        
+        //label.setBackgroundColor({r:255*color.r, g:255*color.g, b:255*color.b, a:config.measure.highlight.opacity})
+      
+        label.sprite.material.useDepth = false;
+        //label.textColor = {r: this.color.r*255, g:  this.color.g*255, b:  this.color.b*255, a: 1} 
+    }else{
+        //label.setBackgroundColor({r: this.color.r*255, g:  this.color.g*255, b:  this.color.b*255, a:config.measure.default.opacity})
+        
+        label.sprite.material.useDepth = true
+        //label.sprite.material.opacity = 0.98
+        //label.textColor = {r: 255, g: 255, b: 255, a: 1} 
+        
+    }  
+    label.updateTexture()  
+}
 
-function setLabelHightState(label, state){
+/* function setLabelHightState(label, state){
     if(state){ 
         label.setBackgroundColor({r: highlightColor.r*255, g: highlightColor.g*255, b: highlightColor.b*255, a:config.measure.highlight.labelOpacity})
         label.sprite.material.useDepth = false;
@@ -1045,6 +1094,11 @@ function setLabelHightState(label, state){
     label.updateTexture() 
     //label.sprite.material.needsUpdate = true 
 }
+ 
+
+   */ 
+
+
 
 
 

+ 30 - 0
src/custom/objects/tool/MeasuringTool.js

@@ -202,6 +202,34 @@ export class MeasuringTool extends THREE.EventDispatcher{
 	update(){
         return;
         
+        viewer.scene.measurements.forEach(measure=>{
+            
+            let lastIndex = measure.points.length - 1; 
+            for (let index = 0; index <= lastIndex; index++) {
+                
+                let nextIndex = (index + 1 > lastIndex) ? 0 : index + 1;
+                let previousIndex = (index === 0) ? lastIndex : index - 1;
+                
+                let point = measure.points[index];
+                let nextPoint = measure.points[nextIndex];
+                let previousPoint = measure.points[previousIndex];
+ 
+                if(measure.showDistances || measure.labelText){ // edge labels
+                    let edgeLabel = measure.edgeLabels[index];
+                  
+                    if(edgeLabel.visible){
+                        measure.setEdgeLabelPos(edgeLabel, point, nextPoint  )
+                    }  
+                }
+            }  
+        })
+        
+        
+        
+        
+        
+        return;
+        
         
         
         
@@ -629,6 +657,8 @@ export class MeasuringTool extends THREE.EventDispatcher{
             this.viewer.ssaaRenderPass.sampleLevel = 4
             this.viewer.composer.render(this.scene, o.camera );  
         }else{ */
+        
+            viewer.dispatchEvent({type: "render.begin2" , name:'measure', viewport:o.viewport  })
             this.viewer.renderer.render(this.scene, o.camera );
         //}
 	}

+ 15 - 13
src/custom/objects/tool/ctrlPolygon.js

@@ -293,7 +293,7 @@ export class ctrlPolygon extends THREE.Object3D {
                 }
             } 
 
-            if(len > 2){ 
+            if(len > 2){  
                 
                 if(!this.faceDirection && this.showArea){ 
                     if(len == 3 || this.isRect) this.cannotConfirmNormal = true //当第三个点固定后(有四个点时)才能固定面
@@ -315,9 +315,16 @@ export class ctrlPolygon extends THREE.Object3D {
                         location = this.facePlane.projectPoint(intersectPos, new THREE.Vector3() )
                     }
                 }  
+                 
+                points[i].copy(location)//再copy确认一次
                 
                 
-                points[i].copy(location)//再copy确认一次
+                if(len == 3 && this.faceDirection == 'horizontal'){ //normal方向还不确定 会影响label在里侧还是外侧
+                    let facePlane = new THREE.Plane().setFromCoplanarPoints(...points)
+                    this.facePlane = facePlane
+                    //console.log(this.facePlane.normal, this.facePlane.constant)
+                }
+                
                 
                 if(this.isRect){ //是矩形 (即使没有faceDirection也能执行)
                     //根据前两个点计算当前和下一个点
@@ -343,12 +350,7 @@ export class ctrlPolygon extends THREE.Object3D {
                     
                 }  
                 
-                /* let points2d;
-                if(this.facePlane){
-                    var originPoint0 = points[0].clone() 
-                    var qua = math.getQuaBetween2Vector(this.facePlane.normal, new THREE.Vector3(0,0,1), new THREE.Vector3(0,0,1));
-                    points2d = points.map(e=>e.clone().applyQuaternion(qua))  
-                } */
+ 
                 this.getPoint2dInfo(points)
                  
                 var isIntersectSelf = this.atPlane && this.closed && !this.isRect && this.point2dInfo && this.intersectSelf(this.point2dInfo.points2d)//检测相交
@@ -487,10 +489,10 @@ export class ctrlPolygon extends THREE.Object3D {
         let facePlane = this.facePlane
         if(!this.atPlane || !facePlane){//多折线 没有实时更新facePlane所以重新算
             let normal = new THREE.Vector3, len = this.points.length - 2
-            for(let i=0;i<len;i++){
-                let vec0 = new THREE.Vector3().subVectors(this.points[i], this.points[i+1])
-                let vec1 = new THREE.Vector3().subVectors(this.points[i+2], this.points[i+1])
-                let nor = vec0.cross(vec1).normalize();
+            for(let i=0;i<len;i++){ //获取normal的顺序方法必须和setFromCoplanarPoints一致
+                let vec0 = new THREE.Vector3().subVectors(this.points[i+2], this.points[i+1], )
+                let vec1 = new THREE.Vector3().subVectors(this.points[i], this.points[i+1])
+                let nor = vec0.cross(vec1).normalize(); 
                 normal.add(nor)
             }
             normal.normalize(); 
@@ -536,7 +538,7 @@ export class ctrlPolygon extends THREE.Object3D {
     
     updateMarker(marker, pos){
         marker.position.copy(pos);
-        marker.update();
+        marker.waitUpdate();
     }
     
     

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

@@ -860,7 +860,7 @@ Utils.setCameraLayers = function(camera, enableLayers, extraEnableLayers=[]){//a
             return 
         }
         camera.layers.enable(layer)
-    })
+    }) 
 }
 Utils.setObjectLayers = function(object, layerName){//add
     let layer = Potree.config.renderLayers[layerName]

+ 2 - 2
src/custom/settings.js

@@ -183,9 +183,9 @@ const config = {//配置参数   不可修改
         ,   
         backColor:'#333333',
          
-        lineWidth: 4,
+        lineWidth: 3,
        
-        textColor: "#FFFFFF",
+        textColor: "#000000" //"#FFFFFF"
         
         
     },

+ 47 - 47
src/custom/start.js

@@ -124,58 +124,58 @@ export function start(dom, mapDom, number ){ //t-Zvd3w0m
                         
                         let bound = viewer.bound.boundingBox.clone() 
                         viewer.focusOnObject({boundingBox:bound},'boundingBox',0,{dontChangeCamDir:true})
-                        if(viewer.bound.boundSize.length() < 20)return //否则有可能超出far范围
+                        if(viewer.bound.boundSize.length() > 20){  //否则有可能超出far范围
                         
                         
-                        viewer.mainViewport.camera.far = 10000;
-                        viewer.mainViewport.camera.updateProjectionMatrix() 
-                        viewer.fixCamFar = true //不允许修改camera.far
-                          
-                        //等有点云加载出来后,再去focus其中一个,使camera.far不超过最大值
-                        let count_ = 0;
-                        let done = ()=>{
-                            viewer.fixCamFar = false
-                            viewer.mainViewport.camera.far = Potree.settings.cameraFar; 
+                            viewer.mainViewport.camera.far = 10000;
                             viewer.mainViewport.camera.updateProjectionMatrix() 
-                            viewer.removeEventListener('pageVisible', focusPoint )
-                        }
-                        let focusPoint = (e)=>{//拉近到某个点
-                            if(e && e.v === false)return
-                            viewer.removeEventListener('pageVisible', focusPoint )
-                       
-                            let pointcloud = viewer.scene.pointclouds.find(e=>e.root.geometryNode)
-                             
-                            console.log('初始加载focus点云', e , pointcloud)
-                             
-                            if(!pointcloud){  
-                                if(count_ < 10 ){//可能没加载到,可能被隐藏
-                                    if(document.hidden){//等回到页面再focus
-                                        console.log('focus hidden')
-                                        return viewer.addEventListener('pageVisible', focusPoint )
-                                    }
-                                    count_ ++ //如果在别的
-                                    setTimeout(focusPoint, 200) 
-                                }else{ //放弃
-                                    console.log('初始加载focus点云 放弃')
-                                    done()
-                                }    
-                                return console.warn('no!!!!!!!!!!!!!!')
-                            }  
-                            viewer.flyToDataset({focusOnPoint:true, pointcloud, duration:0, })
+                            viewer.fixCamFar = true //不允许修改camera.far
+                              
+                            //等有点云加载出来后,再去focus其中一个,使camera.far不超过最大值
+                            let count_ = 0;
+                            let done = ()=>{
+                                viewer.fixCamFar = false
+                                viewer.mainViewport.camera.far = Potree.settings.cameraFar; 
+                                viewer.mainViewport.camera.updateProjectionMatrix() 
+                                viewer.removeEventListener('pageVisible', focusPoint )
+                            }
+                            let focusPoint = (e)=>{//拉近到某个点
+                                if(e && e.v === false)return
+                                viewer.removeEventListener('pageVisible', focusPoint )
+                           
+                                let pointcloud = viewer.scene.pointclouds.find(e=>e.root.geometryNode)
+                                 
+                                console.log('初始加载focus点云', e , pointcloud)
+                                 
+                                if(!pointcloud){  
+                                    if(count_ < 10 ){//可能没加载到,可能被隐藏
+                                        if(document.hidden){//等回到页面再focus
+                                            console.log('focus hidden')
+                                            return viewer.addEventListener('pageVisible', focusPoint )
+                                        }
+                                        count_ ++ //如果在别的
+                                        setTimeout(focusPoint, 200) 
+                                    }else{ //放弃
+                                        console.log('初始加载focus点云 放弃')
+                                        done()
+                                    }    
+                                    return console.warn('no!!!!!!!!!!!!!!')
+                                }  
+                                viewer.flyToDataset({focusOnPoint:true, pointcloud, duration:0, })
+                                
+                                console.warn('ok!!!!!!!!!!!!!!!!')
+                                done()
+                            } 
+                            let focus = ()=>{ 
+                                setTimeout(focusPoint, 300) 
+                            }
+                            viewer.addEventListener('setPose',()=>{//设置了初始画面
+                                viewer.removeEventListener('pointcloud_changed',focus)
+                                done()
+                            })                            
+                            viewer.addEventListener('pointcloud_changed',focus,{once:true})//加载了点之后
                             
-                            console.warn('ok!!!!!!!!!!!!!!!!')
-                            done()
                         } 
-                        let focus = ()=>{ 
-                            setTimeout(focusPoint, 300) 
-                        }
-                        viewer.addEventListener('setPose',()=>{//设置了初始画面
-                            viewer.removeEventListener('pointcloud_changed',focus)
-                            done()
-                        })                            
-                        viewer.addEventListener('pointcloud_changed',focus,{once:true})//加载了点之后
-                        
-                        
                         
                         
                     }

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

@@ -1141,13 +1141,24 @@ export class Viewer extends ViewerBase{
     }
 
     
-    updatePanosVisibles(currentFloor){//显示当前楼层的所有panos 
+    updatePanosVisibles(currentFloor){//显示当前楼层的所有panos  
         if(!Potree.settings.ifShowMarker)return
+        let inEntity = currentFloor
+        if(!inEntity) inEntity = this.atDatasets[0] 
+        
         viewer.images360.panos.forEach(pano=>{
-            let visible = currentFloor && currentFloor.panos.includes(pano) 
+            let visible = inEntity && inEntity.panos.includes(pano) 
             Potree.Utils.updateVisible(pano, 'buildingChange', visible, 2)  
         })
+        this.dispatchEvent('content_changed')
     } //注:非official的没有获取sitemodel的信息所以不执行楼层判断,marker显示不对是正常的
+   
+    /* 2023.11.24 针对部分场景的楼层很矮,很容易就到楼层外了,且不能修改楼高。如SG-t-9NdCpxrUPLL#/,采取如下措施:
+    1 如果不在任何一楼层,但在某个数据集中,就显示该数据集所有的marker
+    2 如果当前楼层无,则显示上一次的currentFloor的marker
+    (目前先使用方案1)
+     */
+    
     
     updateMarkerVisibles(){//限制显示的marker个数,因镜头内marker多的时候可能会卡 
         if(!Potree.settings.ifShowMarker)return
@@ -1174,6 +1185,7 @@ export class Viewer extends ViewerBase{
                 Potree.Utils.updateVisible(pano.marker, 'limitMarkerShow', v )  
             })
             //console.log('updateMarkerVisibles marker显示个数', count)
+            this.dispatchEvent('content_changed')
         }
         let isWithinDis = (pano,maxDis)=>{//是否marker到相机的距离 没有超出可视距离。可视距离考虑上倾斜角,倾斜越大可视距离越短
             let camPos = viewer.mainViewport.camera.position
@@ -3399,7 +3411,7 @@ export class Viewer extends ViewerBase{
                 })//ground的材质中opacity为1,所以被当做不透明了
             }
             
-            
+            viewer.dispatchEvent({type: "render.begin2" , name:'scene', viewport:params.viewport  })
             this.renderer.render(this.scene.scene, camera);  
              
             if('renderBeforeCloud' in params){
@@ -3426,7 +3438,7 @@ export class Viewer extends ViewerBase{
  
         if(!params.magnifier){ 
             //测量线 
-            this.dispatchEvent({type: "render.pass.perspective_overlay", camera, screenshot:params.screenshot});
+            this.dispatchEvent({type: "render.pass.perspective_overlay", camera, screenshot:params.screenshot,viewport:params.viewport});
             
             if(!params.screenshot && params.viewport.name != "mapViewport" ){
                 Potree.Utils.setCameraLayers(camera, ['magnifier']) //magnifier 遮住测量线 
@@ -3436,6 +3448,7 @@ export class Viewer extends ViewerBase{
         
         if(params.viewport.name != "mapViewport" ) {
             Potree.Utils.setCameraLayers(camera, ['volume','transformationTool'])  
+            //viewer.dispatchEvent({type: "render.begin2" , name:'clip&trans',viewport:params.viewport  })
             this.renderer.render(this.clippingTool.sceneVolume, camera);  //official 可以删
             this.renderer.render(this.transformationTool.scene, camera);
         }

+ 16 - 4
src/materials/shaders/depthBasic.fs

@@ -1,10 +1,21 @@
 varying vec2 vUv;
 uniform float opacity;
-
+uniform float mapScale;
 uniform vec3 baseColor;
 
 #if defined use_map
     uniform sampler2D map; 
+    
+    vec4 getMapColor(vec4 color){ 
+        vec2 uv = (vUv - 0.5) / mapScale + 0.5; 
+        if(uv.x > 1.0 || uv.y > 1.0 || uv.x < 0.0 || uv.y < 0.0){
+            //color = vec4(0.0,0.0,0.0,0.0);
+            discard;
+        }else{
+            color = texture2D(map, uv) * color; 
+        }
+        return color; 
+    }
 #endif
  
 #if defined(GL_EXT_frag_depth) && defined(useDepth)  
@@ -33,6 +44,8 @@ uniform vec3 baseColor;
      }
 #endif
   
+ 
+  
 void main() {
   
     
@@ -81,9 +94,8 @@ void main() {
         }else{
             
             #if defined use_map
-                color = texture2D(map, vUv) * color; 
+                color = getMapColor(color); 
             #endif
-           
             
              
             color = vec4(mix(color.rgb, backColor, mixFactor), color.a * (1.0 - clipFactor));
@@ -91,7 +103,7 @@ void main() {
          
     #else
         #if defined use_map
-            color = texture2D(map, vUv) * color;
+            color = getMapColor(color); 
         #endif 
     #endif
   

+ 4 - 6
src/navigation/InputHandlerNew.js

@@ -1332,9 +1332,7 @@ export class InputHandler extends THREE.EventDispatcher {
  
 	getHoveredElements (interactables, dontCheckDis, raycaster) { 
 		
-        if(!interactables){
-             
-             
+        if(!interactables){ 
             let scenes = this.hoverViewport.interactiveScenes || this.interactiveScenes.concat(this.scene);
 
             let interactableListeners = ['mouseup', 'mousemove', 'mouseover', 'mouseleave', 'drag', 'drop', 'click', 'select', 'deselect'];
@@ -1352,7 +1350,7 @@ export class InputHandler extends THREE.EventDispatcher {
                     }
                 });
             }  
-		}  
+		}else interactables = interactables.filter(e=>e.visible)
 		 
 		let camera = this.hoverViewport.camera
         if(!raycaster){ 
@@ -1377,8 +1375,8 @@ export class InputHandler extends THREE.EventDispatcher {
         )
         //this.hoverViewport.beforeRender && this.hoverViewport.beforeRender()
         
-        viewer.dispatchEvent( {type:'raycaster',  viewport: this.hoverViewport})//add
-		let intersections = raycaster.intersectObjects(interactables.filter(o => o.visible), true, null, true); //原本是false 检测不到children
+        viewer.dispatchEvent( {type:'raycaster',  viewport: this.hoverViewport, raycaster, viewer:this.viewer, interactables })//add
+		let intersections = raycaster.intersectObjects(interactables , true, null, true); //原本是false 检测不到children
     
         let intersectionsCopy = intersections.slice()