xzw 2 năm trước cách đây
mục cha
commit
f07d65e725

+ 1 - 1
gulpfile.js

@@ -91,7 +91,7 @@ gulp.task('webserver', gulp.series(async function() {
 	server = connect.server({
 		port: 1234,
         host:'192.168.0.113',
-		https: false,
+		https: true,
 	});
 }));
 

+ 17 - 2
src/PointCloudOctree.js

@@ -274,7 +274,7 @@ export class PointCloudOctree extends PointCloudTree {
             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()//重新计算
              
@@ -2042,11 +2042,26 @@ export class PointCloudOctree extends PointCloudTree {
     updateBound(){
         var boundingBox_ = this.pcoGeometry.tightBoundingBox.clone().applyMatrix4(this.matrixWorld)
         this.bound = boundingBox_
+        this.bound2 = this.getBoundWithPanos()
     }
+    
+    getBoundWithPanos(){//确保pano在内的bound 
+        let bound = this.bound.clone()
+        this.panos.forEach(pano=>{
+            let panoBound = new THREE.Box3
+            panoBound.expandByPoint(pano.position)
+            panoBound.expandByVector(new THREE.Vector3(.1,.1,.1));//give pano a margin
+            bound.union(panoBound)
+        }) 
+        return bound
+    }
+    
+    
+    
     getPanosBound(){
         if(this.panos.length > 0){
             let minSize = new THREE.Vector3(1,1,1)
-            this.panosBound = math.getBoundByPoints(this.panos.map(e=>e.position), minSize)
+            this.panosBound = math.getBoundByPoints(this.panos.map (e=>e.position), minSize)
         }else{
             this.panosBound = null
         } 

+ 4 - 5
src/PointCloudOctreeGeometry.js

@@ -191,16 +191,15 @@ export class PointCloudOctreeGeometryNode extends PointCloudTreeNode{
 			let nodes = {};
 			nodes[node.name] = node;
 			let pco = node.pcoGeometry;
-
+            let maxLevel_ = 0
 			for (let i = 0; i < decoded.length; i++) {
 				let name = decoded[i].name;
 				let decodedNumPoints = decoded[i].numPoints;
 				let index = parseInt(name.charAt(name.length - 1));
 				let parentName = name.substring(0, name.length - 1);
 				let parentNode = nodes[parentName];
-				let level = name.length - 1;
-                pco.dispatchEvent({type:'updateNodeMaxLevel',level});//add
-                
+				let level = name.length - 1; 
+                maxLevel_ = Math.max(maxLevel_,level)//add
 				let boundingBox = Utils.createChildAABB(parentNode.boundingBox, index);
 
 				let currentNode = new PointCloudOctreeGeometryNode(name, pco, boundingBox);
@@ -211,7 +210,7 @@ export class PointCloudOctreeGeometryNode extends PointCloudTreeNode{
 				parentNode.addChild(currentNode);
 				nodes[name] = currentNode;
 			}
-
+            pco.dispatchEvent({type:'updateNodeMaxLevel',level:maxLevel_});//add
 			let duration = performance.now() - tStart;
 			if(duration > 5){
 				/* let msg = `duration: ${duration}ms, numNodes: ${decoded.length}`;

+ 11 - 7
src/materials/ModelTextureMaterial.js

@@ -201,9 +201,12 @@ let shader = {
                     float distance = (depth.g + depth.r / 256.) * 255.;  //为什么要乘以255 
                     
                     if(distance == 0.0){//漫游点底部识别不到的区域,给一个地板高度 
-                         if(uv2.y > 0.75)distance = height / dir.y; 
+                         if(uv2.y > 0.75) distance = height / dir.y; 
                          else distance = 100000.0;//给个超级远的值
                     } 
+                    
+                    if(distance == 0.0)distance = 100000.0;//给个超级远的值
+                    
                     depthValue.x = distance;
                     
                    // return  r[1] + r[0] / 256  
@@ -223,7 +226,8 @@ let shader = {
             
             void main()
             {
-                
+                vec3 vWorldPosition0N = normalize(vWorldPosition0);
+                vec3 vWorldPosition1N = normalize(vWorldPosition1);
                 /* vec2 samplerCoord0 = getSamplerCoord(vWorldPosition0.xyz);
                 vec2 samplerCoord1 = getSamplerCoord(vWorldPosition1.xyz);  
                 vec4 colorFromPano0=texture2D(pano0Map,samplerCoord0);
@@ -231,9 +235,9 @@ let shader = {
                 
                 vec4 colorFromPano0 = vec4(0.0,0.0,0.0,0.0);
                 if(progress < 1.0){//通常是1
-                    colorFromPano0=textureCube(pano0Map,vWorldPosition0.xyz);
+                    colorFromPano0=textureCube(pano0Map,vWorldPosition0N.xyz);
                 }
-                vec4 colorFromPano1=textureCube(pano1Map,vWorldPosition1.xyz);
+                vec4 colorFromPano1=textureCube(pano1Map,vWorldPosition1N.xyz);
  
                 gl_FragColor=mix(colorFromPano0,colorFromPano1,progress);
               
@@ -253,9 +257,9 @@ let shader = {
                     vec4 eyePos = inverseProjectionMatrix * clipPos;
                     vec2 depth0 = vec2(0.0,0.0); 
                     if(progress < 1.0){
-                        depth0 = getDepth(vWorldPosition0, depthMap0, cameraHeight0, eyePos);
+                        depth0 = getDepth(vWorldPosition0N, depthMap0, cameraHeight0, eyePos);
                     }
-                    vec2 depth1 = getDepth(vWorldPosition1, depthMap1, cameraHeight1, eyePos);
+                    vec2 depth1 = getDepth(vWorldPosition1N, depthMap1, cameraHeight1, eyePos);
                     
                     /* if(progress < 1.0 && depth1.x == 0.0 && depth0.x > 0.0){
                         gl_FragDepthEXT = depth0.y; 
@@ -315,7 +319,7 @@ export default class ModelTextureMaterial extends THREE.RawShaderMaterial {
             
             viewer.addEventListener('camera_changed', (e)=>{
                 //this.uniforms.projectionMatrix.value.copy(e.camera.projectionMatrix) 
-                this.uniforms.inverseProjectionMatrix.value.copy(e.camera.projectionMatrixInverse)
+                e.camera && this.uniforms.inverseProjectionMatrix.value.copy(e.camera.projectionMatrixInverse)
             })   
 
         } 

+ 192 - 72
src/modules/Images360/Images360.js

@@ -38,7 +38,7 @@ let previousView = {
 const HighMapCubeWidth = 1
  
  
-const directionFactor = 200 //原先10,几乎只往距离近的走了;设置太大楼梯上不去
+const directionFactor = 400 //原先10,几乎只往距离近的走了;设置太大容易略过近处漫游点走向下坡,因为鼠标一般在地面,下坡的漫游点更有利
  
  
 export class Images360 extends THREE.EventDispatcher{
@@ -276,11 +276,13 @@ export class Images360 extends THREE.EventDispatcher{
                                 //要改成飞进最近的。。。 
                                 if(this.panos.length == 0)return
                                 //this.modeChanging = true //主要是因为到全景图不会立刻成功
-                                let wait = ()=>{
-                                    this.removeEventListener('flyToPanoDone',wait)  
-                                    if(latestRequestMode == mode ){
-                                        Potree.settings.displayMode = mode 
-                                    } 
+                                let wait = (e)=>{
+                                    this.removeEventListener('flyToPanoDone',wait) 
+                                    setTimeout(()=>{
+                                        if(latestRequestMode == mode ){
+                                            Potree.settings.displayMode = mode 
+                                        } 
+                                    },e.makeIt ? 1 : 50) 
                                 }
                                 this.flyToPano({
                                     pano: this.findNearestPano(),   
@@ -622,6 +624,7 @@ export class Images360 extends THREE.EventDispatcher{
 
 
 	cancelFlyToPano(){//取消当前已有的飞行准备,前提是相机还未移动
+        Potree.Log('cancelFlyToPano')
         if(viewer.mainViewport.view.isFlying())return
         this.nextPano = null 
         this.latestToPano = null
@@ -681,13 +684,13 @@ export class Images360 extends THREE.EventDispatcher{
         this.nextPano = pano 
         this.latestToPano = toPano
         //this.flying = true  //防止新的请求
-        
+        Potree.Log('flyToPano:'+pano.id + ' , duration:'+toPano.duration)
         
         
         {//不飞的话是否不要执行这段?
             
             let wait = ()=> {
-                if(this.latestToPano != toPano)return //如果取消了
+                if(this.latestToPano != toPano)return Potree.Log('已经取消')//如果取消了
                 setTimeout(()=>{ 
                     if(this.latestToPano != toPano)return
                     this.flyToPano(toPano) 
@@ -952,9 +955,8 @@ export class Images360 extends THREE.EventDispatcher{
 
     updateCube(pano0, pano1){
         
-        if(!viewer.scene.pointclouds.some(e=>!e.hasDepthTex))   return this.updateCube2(pano0, pano1) //都hasDepthTex的话
-        
         if(Potree.settings.displayMode != 'showPanos')return
+        if(!viewer.scene.pointclouds.some(e=>!e.hasDepthTex))   return this.updateCube2(pano0, pano1) //都hasDepthTex的话
         
        
         let f = (bound, size)=>{
@@ -1342,12 +1344,18 @@ export class Images360 extends THREE.EventDispatcher{
                 return vec.clone().applyMatrix4(rotMat) 
             }
             let getFar = (dir, pano, origin)=>{//获取在这个方向上和墙体intersect的最远距离 
+                let r = (pano.ceilZ - pano.floorPosition.z) * 0.14  // 高度约小,角度越小
+                let getAngle = (deg)=>{
+                    deg *= r 
+                    deg = THREE.Math.clamp(deg, 1,  80);
+                    return deg
+                }
                 let dirs_ = [
                     //注意:角度太大会碰到天花板或地板,越远越容易碰到, 在地下停车场就会伸展不开。 户外时需要更多向上的方向,所以上方向多一个
-                    dir.clone().setZ(Math.tan(THREE.Math.degToRad(30))).normalize(), 
-                    dir.clone().setZ(Math.tan(THREE.Math.degToRad(7))).normalize(), 
+                    dir.clone().setZ(Math.tan(getAngle(30))).normalize(), 
+                    dir.clone().setZ(Math.tan(getAngle(7))).normalize(), 
                     dir.clone(),            // 水平方向
-                    dir.clone().setZ(-Math.tan(THREE.Math.degToRad(5))).normalize(), 
+                    dir.clone().setZ(-Math.tan(getAngle(5))).normalize(), 
                     //dir.clone().setZ(-Math.tan(THREE.Math.degToRad(30))).normalize(), 
                 ]; 
                 
@@ -1578,8 +1586,7 @@ export class Images360 extends THREE.EventDispatcher{
         
         //console.log('updateCube',pano0.id, pano1&&pano1.id)
         
-        let useBound = (bound, size)=>{
-           
+        let useBound = (bound, size)=>{ 
             size = size || bound.getSize(new THREE.Vector3) 
             let center = bound.getCenter(new THREE.Vector3)
             size.max(new THREE.Vector3(HighMapCubeWidth,HighMapCubeWidth,HighMapCubeWidth))
@@ -1589,14 +1596,21 @@ export class Images360 extends THREE.EventDispatcher{
         }
         
         
+        let getPanoBound = (pano)=>{//因漫游点可能在点云外部,如室外平地,所以需要union进漫游点
+            let panoBound = new THREE.Box3
+            panoBound.expandByPoint(pano.position)
+            panoBound.expandByVector(new THREE.Vector3(10,10,10));//give pano a margin
+            return pano.pointcloud.bound.clone().union(panoBound)
+        }
+        
         this.cube.geometry.dispose();
         
         if(pano1){//过渡  
             
             if(pano0.pointcloud != pano1.pointcloud){ //距离太远的数据集,过渡会畸变。所以扩大skybox
                 let dis = pano0.position.distanceTo(pano1.position)
-                if(dis > 100){
-                    let bound = pano0.pointcloud.bound.clone().union(pano1.pointcloud.bound)
+                if(dis > 100){ 
+                    let bound = getPanoBound(pano0).union(getPanoBound(pano1))
                     let size = bound.getSize(new THREE.Vector3) 
                     let max = Math.max(size.x, size.y, size.z)
                     size.set(max,max,max)
@@ -1628,12 +1642,22 @@ export class Images360 extends THREE.EventDispatcher{
             }
             let getFar = (dir, pano, origin)=>{//获取在这个方向上和墙体intersect的距离  
                 //在垂直方向上分出多个方向,取一个最可能的接近真实的距离
+                let maxH = 40, minH = 2, height = pano.ceilZ - pano.floorPosition.z, minR = 0.5, maxR = 2  
+                //let r = height (maxH - minH)* 0.14  // 高度约小,角度越小 
+                let r = minR + ( maxR - minR) * THREE.Math.clamp((height - minH)  / (maxH - minH),0,1)   //THREE.Math.smoothstep(currentDis,  op.nearBound,  op.farBound);
+                 
+                let getZ = (deg)=>{
+                    deg *= r 
+                    deg = THREE.Math.clamp(deg, 1,  80);
+                    return Math.tan(THREE.Math.degToRad(deg))
+                }
                 let dirs_ = [
                     //注意:角度太大会碰到天花板或地板,越远越容易碰到, 在地下停车场就会伸展不开。 户外时需要更多向上的方向,所以上方向多一个
-                    dir.clone().setZ(Math.tan(THREE.Math.degToRad(30))).normalize(), 
-                    dir.clone().setZ(Math.tan(THREE.Math.degToRad(7))).normalize(), 
+                    dir.clone().setZ(getZ(30)).normalize(), 
+                    dir.clone().setZ(getZ(15)).normalize(), 
+                    dir.clone().setZ(getZ(7)).normalize(), 
                     dir.clone(),            // 水平方向
-                    dir.clone().setZ(-Math.tan(THREE.Math.degToRad(5))).normalize(), 
+                    dir.clone().setZ(-getZ(5)).normalize(), 
                     //dir.clone().setZ(-Math.tan(THREE.Math.degToRad(30))).normalize(), 
                 ]; 
                 
@@ -1644,6 +1668,7 @@ export class Images360 extends THREE.EventDispatcher{
                     let projectLen = intersect && intersect.distance ? dir_.dot(dir)*intersect.distance : max; //得到project在dir的长度 
                     return projectLen //得水平距离
                 }) 
+                //console.log(pano ? pano.id : 'side','disArr', disArr.slice(0))
                 disArr.sort((a,b)=>{return b-a}); //从大到小
                 //console.log(pano ? pano.id : 'side','disArr', disArr)
                 let dis = disArr[Math.floor(count2/2-0.5)] //对半、取前(中位数) 
@@ -1695,26 +1720,80 @@ export class Images360 extends THREE.EventDispatcher{
                 for(let i=0;i<count1;i++){ 
                     dirs.push(getDir(Math.PI/2-i*angle, vec))//正的在左边
                 } 
-                 
-                
+                  
+                  
+                let dirs2 = dirs.map((dir)=>{
+                    return {
+                        dir,
+                        dis: getFar(dir, pano)  
+                    }   
+                })
                 
-                // let sideDis = []
-                dirs.forEach((dir, index)=>{
-                    let dis = getFar(dir, pano);
-                    // if(index == 0 || index == count1-1){
-                        // sideDis.push(dis)
-                    // }
-                    dir.multiplyScalar( dis ); 
+                //剔除那些突然间离相机很近的dir。有可能是拍摄的人、或者杆子、树
+                const maxRatio = 8  
+                /* dirs2.forEach((e,i)=>{
+                    console.log(i,  e.dis)
+                    let smallThanBefore = ()=>{
+                        return dirs2[i-1].dis / e.dis > maxRatio 
+                    }
+                    let smallThanAfter = ()=>{
+                        return dirs2[i+1].dis / e.dis > maxRatio 
+                    }
+                     
+                    if(i>0 && i<count1-1 && smallThanBefore() && smallThanAfter()){//比左右两边都小很多
+                        e.disB = (dirs2[i-1].dis + dirs2[i+1].dis) / 2   //平均数
+                        console.log('两者之间',i,e.disB)    
+                    }else if(i==count1-1 && smallThanBefore() ) {//比前者小很多
+                        e.disB =  dirs2[i-1].dis * 0.8
+                        console.log('smallThanBefore', i, e.disB)    
+                    }else if(i==0 && smallThanAfter() ){//比后者小很多
+                        e.disB =  dirs2[i+1].dis * 0.8
+                        console.log('smallThanAftere', i, e.disB)    
+                    }                        
                     
+                }) */
+                const minWidth = 0.5 
+                let computeWidth = (start,end)=>{
+                    start+=1 //不包含start和end
+                    let count = end - start ; 
+                    let dis = 0
+                    for(let m=start;m<end;m++){//得平均数
+                        dis += dirs2[m].dis
+                    }
+                    dis /= count
+                    let angle = Math.PI / (count1-1) * count / 2
+                    let width = dis * Math.tan(angle) //得到block的半宽度
+                    return width
+                }
+                let changeDis = (start,end )=>{ //不包含start
+                    start+=1 //不包含start和end
+                    for(let m=start;m<end;m++){ 
+                        dirs2[m].disB = dirs2[end].dis * 0.8
+                        console.log('changeDis', m, dirs2[m].disB) 
+                    }
+                }
+                let start = -1 
+                for(let i=0;i<count1;i++){//遍历时将左边dis比之小很多且宽度较小的改大 
+                    //console.log(i, dirs2[i].dis) 
+                    let j = i-1
+                    while(j>start && dirs2[i].dis / dirs2[j].dis > maxRatio){
+                        j--    
+                    } 
+                    let count = i-j
+                    if(count > 1 && (count == 2 || computeWidth(j,i)<minWidth)){//若只有一个不用判断宽度直接修改,count == 2 即只有一个
+                        changeDis(j,i)  
+                        start = i  //在此之前的修改过,之后不用再判断
+                    }
+                } 
+                 
+                 
+                dirs2.forEach((e, index)=>{
+                    let dir = e.dir.clone().multiplyScalar(e.disB || e.dis);
                     [maxZ,minZ].forEach(z=>{  
                         posArr.push(pano.position.clone().setZ(z).add(dir))  //获取到外墙点
-                    })
-                        
-                     
+                    })   
                 }); 
-                 
-                //panoIndex ++
-                //return sideDis;
+                
             }
             
             
@@ -1897,7 +1976,7 @@ export class Images360 extends THREE.EventDispatcher{
             //this.cube.position.copy(pano1.position).multiplyScalar(-100)   
         }else{ 
             
-            useBound(pano0.pointcloud.bound) 
+            useBound(getPanoBound(pano0)) 
         }
     } 
 
@@ -2010,6 +2089,8 @@ export class Images360 extends THREE.EventDispatcher{
         return this.rankedPanoInDirection(0, direction, option1, option2)
     }
     rankedPanoInDirection(t, direction, option1, option2){
+        //此direction为mouseDirection,是否需要加上相机角度的权重
+        
         var panoSet = {
             pano: null,
             candidates: [] //缓存顺序--如果需要打印的话
@@ -2025,8 +2106,7 @@ export class Images360 extends THREE.EventDispatcher{
                 return this.position.z - pano.position.z  
             }else{
                 return 0
-            } 
-            
+            }  
         }
         
         
@@ -2050,18 +2130,15 @@ export class Images360 extends THREE.EventDispatcher{
         
         
         var list = [//决胜项目
-            Images360.scoreFunctions.distanceSquared(this.position,1, true),
+            Images360.scoreFunctions.distanceSquared(this.position, 1  ),
             
             Images360.scoreFunctions[o]( this.position, direction,true),
-            
              
             (pano)=>{
-                let neighbour = this.isNeighbour(this.currentPano, pano)
-                //console.log('neighbour', pano.id, neighbour ? directionFactor*0.4 : 0)
-                return neighbour ? directionFactor*1 : 0; 
+                let neighbour = this.isNeighbour(this.currentPano, pano) 
+                return neighbour ? directionFactor  : 0; 
             } 
-            
-            
+             
             /* (pano)=>{//尽量不穿越地板到下一层
                 let dis = getHeightDis(pano)
                 return -dis * directionFactor * 0.1;
@@ -2075,14 +2152,13 @@ export class Images360 extends THREE.EventDispatcher{
                 } 
             } */
         ]; 
-        if(viewer.inputHandler.intersectPoint && this.currentPano ){//方便上下楼, 考虑panos之间的角度差
-            let pos1 = this.currentPano.floorPosition
-            let vec1 = new THREE.Vector3().subVectors(viewer.inputHandler.intersectPoint.location, pos1 ).normalize()//应该只有atPano时才会执行到这吧? 
+        if(viewer.inputHandler.intersect && this.currentPano ){//方便上下楼, 考虑panos之间的角度差
+            let pos1 = this.currentPano.floorPosition 
+            let vec1 = new THREE.Vector3().subVectors(viewer.inputHandler.intersect.location, pos1 ).normalize()//应该只有atPano时才会执行到这吧? 
             list.push(  function(pano) { 
                 var pos2 = pano.floorPosition; 
-                var vec2 = pos2.clone().sub(pos1).normalize();
-                //console.log('direction2', pano.id, vec2.dot(vec1) * directionFactor * 1  );
-                return vec2.dot(vec1) * directionFactor * 1  
+                var vec2 = pos2.clone().sub(pos1).normalize(); 
+                return vec2.dot(vec1) * directionFactor * 4 
             })
         } 
          
@@ -2098,7 +2174,7 @@ export class Images360 extends THREE.EventDispatcher{
         n.pano = null),
         e || (e = 0);
         var r = Common.sortByScore(this.panos, t, i);
-        //console.log('findRankedByScore', r && r.map(u=>u.item.id + '|' + u.score))
+        //console.log('findRankedByScore', r && r.map(u=>u.item.id + '|  ' + math.toPrecision(u.score,4) + "  | " + math.toPrecision(u.scores,4)))
         
         
         return !r || 0 === r.length || e >= r.length ? null : (n && (n.candidates = r,
@@ -2108,7 +2184,11 @@ export class Images360 extends THREE.EventDispatcher{
     
 
     isNeighbour(pano0, pano1){//是否之间没有遮挡(在加载visibles之前,自己算) 最好pano0是currentPano
+         
         if(!pano0 || !pano1)return
+        
+        let margin = 0.1;
+        
         let map0 = this.neighbourMap[pano0.id];
         if(!map0){
             map0 = {}
@@ -2119,26 +2199,61 @@ export class Images360 extends THREE.EventDispatcher{
             map1 = {}
             this.neighbourMap[pano1.id] = map1
         }
-        
+        //三个方向 : position0到position1, position0到floorPosition1, position1到floorPosition0。 只要有一个满足ifNeighbour就为true
+        //0能看到1不代表1能看到0; 但只要有一方能完全看到另一方,无论是position还是floorPosition都算是neighbor
          
-        let ifNeighbour = map0[pano1.id]//map0.get(pano1)
+        let ifNeighbour = map0[pano1.id] || map1[pano0.id]
         
-        if(ifNeighbour == void 0){
-            ifNeighbour = true
+        let getNeighbour = (mainPano, subPano, jumpStep1)=>{
+            //暂时只判断到pano,不判断到marker的方向
+            let dir = new THREE.Vector3().subVectors(subPano.position, mainPano.position).normalize();
             
-            let margin = 0.1;
+            let dirPoints = []
+            if(!jumpStep1){//跳过此步骤,因为之前算过不成功(虽然用另一个漫游点算的可能拍摄时间不同所以有概率不一样,如人走动)
+                dirPoints.push([subPano.position, mainPano.position])
+            }
+            dirPoints.push([subPano.floorPosition.clone().add(new THREE.Vector3(0,0,0.1)), mainPano.position])
             
-            let usePointcloud = pano0.depthTex
-            if(pano0.depthTex || pano1.depthTex){
-                let mainPano = pano0.depthTex ? pano0 : pano1;
-                let subPano = pano0.depthTex ? pano1 : pano0;
-                
-                //暂时只判断到pano,不判断到marker的方向
-                let dir = new THREE.Vector3().subVectors(subPano.position, mainPano.position).normalize();
+            for(let i=0; i<dirPoints.length; i++){
+                let dir = new THREE.Vector3().subVectors(dirPoints[i][0], dirPoints[i][1]).normalize();
                 let intersectPoint = viewer.images360.depthSampler.sample({dir}, mainPano, true) 
-                if(intersectPoint && intersectPoint.distance+margin <= pano0.position.distanceTo(pano1.position)){
-                    ifNeighbour = false
+                if(!intersectPoint || intersectPoint.distance+margin > pano0.position.distanceTo(pano1.position)){ 
+                    return true
                 }
+            }
+            
+        } 
+             
+            //let usePointcloud = pano0.depthTex
+            
+        if(!ifNeighbour) {   
+            if(pano0.depthTex || pano1.depthTex){
+                    
+                if(map0[pano1.id] == void 0 || map1[pano0.id] == void 0 ){
+                    
+                    let mainPano = pano0.depthTex ? pano0 : pano1;
+                    let subPano = pano0.depthTex ? pano1 : pano0;
+                    //let notPosNeighbor = false
+                    if(map0[pano1.id] == void 0 && pano0.depthTex){
+                        let is = getNeighbour(pano0, pano1)
+                        if(is){
+                            ifNeighbour = true
+                        } 
+                        map0[pano1.id] = !!is        
+                    }
+                    
+                    if(!ifNeighbour && map1[pano0.id] == void 0 && pano1.depthTex){
+                        let is = getNeighbour(pano1, pano0, !ifNeighbour)
+                        if(is){
+                            ifNeighbour = true
+                        } 
+                        map1[pano0.id] = !!is        
+                    }
+                    
+                    /* if(ifNeighbour){ //需要标记成全部true吗,不标记也能get到,但标记了更直观,不标记保留信息更多
+                        map0[pano1.id] = map1[pano0.id] = true
+                    } */
+                }    
             }else{
                 //使用点云判断(有深度贴图时不会执行到这)
                 ifNeighbour = !viewer.inputHandler.ifBlockedByIntersect(pano1.position, margin, true, pano0.position)
@@ -2153,11 +2268,10 @@ export class Images360 extends THREE.EventDispatcher{
                         ifNeighbour = undefined //不确定
                     }
                 }
+                map0[pano1.id] = map1[pano0.id] = ifNeighbour //写简单点
             }
-            
-            map0[pano1.id] = ifNeighbour//map0.set(pano1, ifNeighbour)
-            map1[pano0.id] = ifNeighbour//map1.set(pano0, ifNeighbour)
-        }
+        }    
+         
         return ifNeighbour
     }
 
@@ -2965,12 +3079,18 @@ Images360.scoreFunctions = {
         }   
        
     },
-     
-    distanceSquared: function(pos1, r, ifLog) { 
+    distance: function(pos1, r, ifLog) { 
         if(pos1.position)pos1 = pos1.position
         return  function(pano) {//许钟文 改
             var pos2 = pano.position.clone()
             //ifLog && console.log('distanceSquared', pano.id, pos1.distanceToSquared(pos2) * -1 )
+            return pos1.distanceTo(pos2) * -1 * r;
+        }
+    }, 
+    distanceSquared: function(pos1, r ) { 
+        if(pos1.position)pos1 = pos1.position
+        return  function(pano) {//许钟文 改
+            var pos2 = pano.position.clone() 
             return pos1.distanceToSquared(pos2) * -1 * r;
         }
     },

+ 14 - 13
src/modules/Images360/Panorama.js

@@ -14,9 +14,20 @@ const labelProp = {
     backgroundColor:{r: 255, g: 255, b: 255, a: 0.4 },
     textColor:{r: 0, g: 0, b: 0, a: 1 }, 
     borderRadius: 15,
-    renderOrder:10
+    renderOrder:10,
+    useDepth:true, 
+    clipDistance: 30, maxClipFactor:0.3, occlusionDistance:3, 
+}
+const labelProp2 = {
+    //sizeInfo: {minSize : 200 ,  maxSize : 250,   nearBound : 0.8, farBound : 10},
+    backgroundColor:{r: 255, g: 255, b: 255, a: 0 },
+    textColor:{r:255 , g: 255, b: 255, a: 1 }, 
+    textBorderColor:{r:30 , g:30, b: 30, a: 1 }, 
+    textBorderThick:3,
+    dontFixOrient:true,
+    renderOrder:10,
+    fontsize:30,
 }
-
 let standardMarkerMat 
 let markerTex
 let getMarerMat = function(){
@@ -557,17 +568,7 @@ class Panorama extends THREE.EventDispatcher{
         this.floorPosition && this.label.position.copy(this.floorPosition)
     }
     
-    createTextLabel2(){ 
-        let labelProp2 = {
-            //sizeInfo: {minSize : 200 ,  maxSize : 250,   nearBound : 0.8, farBound : 10},
-            backgroundColor:{r: 255, g: 255, b: 255, a: 0 },
-            textColor:{r:255 , g: 255, b: 255, a: 1 }, 
-            textBorderColor:{r:30 , g:30, b: 30, a: 1 }, 
-            textBorderThick:3,
-            dontFixOrient:true,
-            renderOrder:10,
-            fontsize:30,
-        } 
+    createTextLabel2(){  
         this.label2 = new TextSprite(Object.assign({},
            labelProp2, {text: /* this.originID  */   parseInt(this.id)+1   }) //{text: `id:${this.id}, dataset:${this.pointcloud.name}, 4dkkId:${this.originID}`}
         ); 

+ 19 - 12
src/modules/Images360/tile/PanoRenderer.js

@@ -149,7 +149,7 @@ class PanoRenderer extends THREE.EventDispatcher{
             r && this.deactiveDescripor(r.renderTarget) 
             r = this.activeDescripor(l)  
             if (!r) { 
-                var ren = this.initTiledPano(l, !1); 
+                var ren = this.initTiledPano(l, true); 
                 r = this.initDescriptor(ren.width);
                 r.renderTarget = ren;
             }
@@ -169,15 +169,16 @@ class PanoRenderer extends THREE.EventDispatcher{
             
     }
 
-    deactivateTiledPano(e) {
-        var t = this.getActiveRenderTargetDescriptor(e.id);
+    deactivateTiledPano(pano) {
+        var t = this.getActiveRenderTargetDescriptor(pano.id);
         if(this.isRenderTargetDescriptorValid(t)){
             this.deactiveDescripor(t.renderTarget)
-            this.setActiveRenderTargetDescriptor(e.id, null);
+            this.setActiveRenderTargetDescriptor(pano.id, null);
         }
-        var i = this.getUploadQueueForPano(e.id);
+        var i = this.getUploadQueueForPano(pano.id);
         this.clearUploadQueue(i)
         this.updateActivePanos()
+        viewer.cancelLoad(pano)//add
     }
 
 
@@ -254,7 +255,7 @@ class PanoRenderer extends THREE.EventDispatcher{
      * @param {number} size 当前的panoSize,每个面的分辨率
      */
     
-    initTiledPano(size, t) {//创建 RenderTargetCube
+    initTiledPano(size, ifNormalFilter) {//创建 RenderTargetCube
         var renderer = this.viewer.renderer
         var renderTarget, texture;
             renderTarget = new THREE.WebGLCubeRenderTarget(size,{ //THREE.WebGLRenderTargetCube(size, size, {
@@ -265,14 +266,18 @@ class PanoRenderer extends THREE.EventDispatcher{
         texture.flipY = !0, 
         texture.format = THREE.RGBAFormat
         
-        t ? (texture.generateMipmaps = !0,
+        ifNormalFilter ? (texture.generateMipmaps = !0,
         texture.magFilter = THREE.LinearFilter,
         texture.minFilter = THREE.LinearMipMapLinearFilter) 
         :  (texture.generateMipmaps = !1,
-        texture.magFilter = THREE.LinearFilter,
-        texture.minFilter = THREE.LinearFilter) 
+        texture.magFilter = THREE.LinearFilter,  //LinearFilter更清晰,但锯齿噪点严重,相当于锐化,其实失真了。对于条纹状的画面移动镜头时锯齿明显 眩晕
+        texture.minFilter = THREE.LinearFilter)   
+        
+        //平时还是直接用LinearMipMapLinearFilter,其实并非不清晰,只是没有加锐化,像加了层柔光和抗锯齿,观感更好。放大后使用LinearFilter
         
         
+        
+        renderTarget.texture = texture //居然漏了一句,2022.10.9补
         renderer.setRenderTarget(renderTarget);
         renderer.setRenderTarget(null);
         var o = renderer.properties.get(texture); 
@@ -301,12 +306,12 @@ class PanoRenderer extends THREE.EventDispatcher{
 
     queueTileUpload(e, t, i) {
         var n = this.getActiveRenderTargetDescriptor(e.panoId); 
-  
+    
         if (this.isRenderTargetDescriptorValid(n) && e.downloaded && !this.isTileUploaded(e) && (!e.uploadQueued || i) 
             && (!(e.panoSize > this.qualityManager.getMaxNavPanoSize())|| this.zoomingActive)) {
             
             var r = this.getUploadQueueForPano(e.panoId);
-            
+            //console.log(window.sceneName, 'queueTileUpload: ', e.panoId, e.tileIndex,   i)
             if(i){
                 this.uploadTile(e, !1)//提交
             }else{
@@ -752,7 +757,7 @@ PanoRenderer.prototype.setupZoomRenderTarget = function(){
             if(targets[size]){
                 this.zoomRenderTarget = targets[size]
             }else{
-                this.zoomRenderTarget = this.initTiledPano(size, !1)
+                this.zoomRenderTarget = this.initTiledPano(size, false  )
                 targets[size] = this.zoomRenderTarget
             }
             
@@ -878,6 +883,8 @@ PanoRenderer.prototype.uploadTile = function () {//重写
             renderTarget = this.zoomRenderTarget;
             size =  this.zoomRenderTarget.width   //this.qualityManager.getMaxZoomPanoSize(); //放大后可能2048或4096
         } 
+        //console.log(window.sceneName, 'uploadTile ', id, tileIndex)
+        
         
         let done = ()=>{ 
             if(!LodDescripor.uploaded.includes(tileIndex)){//已经upload过(本来这时候直接返回,但发现缩放后这不会归零,导致清晰度不更新,所以还是redraw且emit吧)

+ 13 - 4
src/modules/Images360/tile/TileDownloader.js

@@ -218,8 +218,8 @@ class TileDownloader extends THREE.EventDispatcher{
     startDownload(e) {//开始下载啦
         //console.log('startDownload')
         
-        startdownloads.push(e)
-        
+        startdownloads.push(e) 
+        e.local2SrcFailed = this.local2SrcFailed
         e.status = DownloadStatus.Downloading;
         var t = this.getTileUrl(e/* e.pano.id, e.panoSize, e.tileSize, e.tileIndex, e.pano.alignmentType */);//xzw add alignmentType
         if(!t)return;
@@ -227,7 +227,16 @@ class TileDownloader extends THREE.EventDispatcher{
         this.loadImage(t, TileDownloader.DOWNLOAD_RETRIES, this.downloadComplete.bind(this, e), this.downloadFailed.bind(this, e))
     }
 
-    downloadFailed(e, t) {}
+    downloadFailed(e, t) {
+        //add 
+        if(Potree.settings.isLocal2 && !e.local2SrcFailed){//为了兼容旧的数据src,如果新src没加载成功,就加载旧的
+            e.local2SrcFailed = this.local2SrcFailed = true
+            //this.startDownload(e)//重新下载
+            var t = this.getTileUrl(e); 
+            this.loadImage(t, TileDownloader.DOWNLOAD_RETRIES, this.downloadComplete.bind(this, e), this.downloadFailed.bind(this, e))
+ 
+        }
+    }
 
     downloadComplete(e, t) {//下载成功时
         //if (e.panoGroupId === this.panoGroupId) {
@@ -351,7 +360,7 @@ class TileDownloader extends THREE.EventDispatcher{
     
 
     getTiles(d, sceneNum){
-        if(Potree.settings.isLocal2){//新的地址  scene_view_data/场景码/images/tiles
+        if(Potree.settings.isLocal2 && !this.local2SrcFailed){//新的地址  scene_view_data/场景码/images/tiles
             return `${Potree.settings.urls.prefix3}/scene_view_data/${sceneNum}/images/${d}`    
         }
         

+ 2 - 2
src/modules/datasetAlignment/Alignment.js

@@ -288,8 +288,8 @@ var Alignment = {
         }) 
         
         viewer.viewports.find(e=>e.name == 'mapViewport').alignment = {rotate:true,translate:true};
-        viewer.viewports.find(e=>e.name == 'right').alignment = {translate:true};
-        viewer.viewports.find(e=>e.name == 'back').alignment = {translate:true};
+        viewer.viewports.find(e=>e.name == 'right').alignment = {translate:true, translateVec:new THREE.Vector3(0,0,1)}; //只能上下移动
+        viewer.viewports.find(e=>e.name == 'back').alignment = {translate:true, translateVec:new THREE.Vector3(0,0,1)}; //只能上下移动
         
         
         this.editing = true

+ 12 - 101
src/modules/panoEdit/panoEditor.js

@@ -13,7 +13,7 @@ import SplitScreen from "../../utils/SplitScreen.js"
 
 
 
-
+let clickPanoToLink = false;//是否在编辑漫游点连接时,通过点击漫游点能修改连接
 let images360, Alignment,  SiteModel 
 
 const texLoader = new THREE.TextureLoader() 
@@ -222,7 +222,7 @@ class PanoEditor extends THREE.EventDispatcher{
             
             
              
-            /* {//旋转时的辅助线
+            /* {//旋转时的辅助线--绕某个点旋转的版本
                 this.rotGuideLine = LineDraw.createLine([], {color:'#aaffee'})
                 this.rotGuideLine.visible = false
                 this.rotGuideLine.name = 'rotGuideLine'
@@ -478,7 +478,7 @@ class PanoEditor extends THREE.EventDispatcher{
             
             if(name == 'top') viewer.mainViewport.alignment = {rotate:true,translate:true};
             if(name == 'right'){
-                viewer.mainViewport.alignment = {translate:true, rotateSide:true}; 
+                viewer.mainViewport.alignment = {translate:true, rotateSide:true, translateVec:new THREE.Vector3(0,0,1)}; //只能上下移动
                 viewer.mainViewport.rotateSide = true
             }else{
                 viewer.mainViewport.rotateSide = false
@@ -495,49 +495,17 @@ class PanoEditor extends THREE.EventDispatcher{
     }
     
     
-    //new THREE.Plane().setFromNormalAndCoplanarPoint( normal, this.points[0]  )
-    
-    viewportFitBound(/* name, boundSize_, target */){  //使一个viewport聚焦在某个范围
-        /* let viewport = viewer.mainViewport 
-        let {boundSize, center} = viewer.bound
     
-        var prop = cameraProps.find(v => name == v.name )
-        
-        let expand = 10;
-        
-        targetPlane.setFromNormalAndCoplanarPoint( prop.direction.clone(), center ) 
-        let shiftTarget = targetPlane.projectPoint(target, new THREE.Vector3() )  //target转换到过模型中心的平面,以保证镜头一定在模型外
-       
-        this.setCameraPose(shiftTarget, prop.direction) 
-         
-         
-        if(name == 'top'){
-            let axis = prop.axis 
-            var width = Math.max(boundSize_[axis[0]],  boundSize_[axis[1]] * viewport.camera.aspect)//视口宽度(米)
-        }else{//因为侧面可能旋转
-            
-            let vec1 = new THREE.Vector3(boundSize_.x, 0,0);
-            let vec2 = new THREE.Vector3(0,boundSize_.y,0);
-            let v1 = vec1.projectOnPlane( prop.direction.clone() )  
-            let v2 = vec2.projectOnPlane( prop.direction.clone() )  
-            
-            
-            var width = Math.max(v1.length()+v2.length(),    boundSize_.z * viewport.camera.aspect)//视口宽度(米)
-        }
-         
-        var margin = 50 //px
-        viewport.camera.zoom = (viewport.resolution.x - margin) / width  
-        viewport.camera.updateProjectionMatrix() */
-        
+    viewportFitBound(){  //使一个viewport聚焦在某个范围
+      
         if(viewer.mainViewport.resolution.x == 0 || viewer.mainViewport.resolution.y == 0){
             return setTimeout(()=>{
-                this.viewportFitBound(/* name, boundSize_, target */)
+                this.viewportFitBound()
             },10)
         }
          
         this.gotoFloor(this.currentFloor, true, 0, null, true)
         
-        
     } 
     
     
@@ -545,44 +513,6 @@ class PanoEditor extends THREE.EventDispatcher{
         this.splitScreenTool.rotateSideCamera(viewer.mainViewport, angle) 
     }
     
-    /* rotateSideCamera(angle){//侧视图绕模型中心水平旋转
-        var prop = cameraProps.find(v => v.name == 'right' )
-        
-        let {boundSize, center} = viewer.bound
-         
-         
-        //找到平移向量
-        targetPlane.setFromNormalAndCoplanarPoint(viewer.mainViewport.view.direction  , center ) 
-        targetPlane.projectPoint(viewer.mainViewport.view.position,  this.shiftTarget )  //target转换到过模型中心的平面,以保证镜头一定在模型外
-        let vec = new THREE.Vector3().subVectors(center, this.shiftTarget)//相对于中心的偏移值,旋转后偏移值也旋转
-        
-        //旋转
-        var rotMatrix = new THREE.Matrix4().makeRotationAxis(new THREE.Vector3(0,0,1), angle) 
-        //prop.direction.applyMatrix4(rotMatrix)
-        viewer.mainViewport.view.direction = viewer.mainViewport.view.direction.applyMatrix4(rotMatrix)
-         
-         
-        vec.applyMatrix4(rotMatrix)
-        this.shiftTarget.subVectors(center,vec) //新的
-        
-        
-        viewer.mainViewport.view.position = this.splitScreenTool.getPosOutOfModel(viewer.mainViewport)  // this.getPosOutOfModel()
-  
-        
-    } */
-     
-    
-    /* getPosOutOfModel(){//已知shiftTarget和currentDir后
-        let {boundSize, center} = viewer.bound
-        let expand = 10;
-        let view = viewer.mainViewport.view
-        let radius = boundSize.length() / 2  
-        let position = this.shiftTarget.clone().sub(view.direction.clone().multiplyScalar(radius + expand))  
-         
-        return position 
-         
-        
-    } */
     
     zoomIn(intersect, pointer){ 
         let camera = viewer.mainViewport.camera
@@ -594,21 +524,11 @@ class PanoEditor extends THREE.EventDispatcher{
         viewer.mainViewport.view.zoomOrthoCamera(camera, endZoom, pointer, 300) 
     
     }
-    /* getRadius(){
-        let {boundSize, center} = viewer.bound
-        let expand = 10;
-        let radius = boundSize.length() / 2  
-        return radius + expand 
-    } */
+   
     moveFit(pos, info, duration){  
         var margin = {x:200, y:230}      
         this.splitScreenTool.viewportFitBound(viewer.mainViewport,  info.bound,  pos, duration, margin )
-        /* targetPlane.projectPoint(pos, this.shiftTarget)  //target转换到过模型中心的平面,以保证镜头一定在模型外 this.shiftTarget是得到的
-        info.endPosition = this.getPosOutOfModel() 
-        info
-        let view = viewer.mainViewport.view 
-        view.moveOrthoCamera(viewer.mainViewport, info ,  duration   ) */
- 
+         
     }
     
     setZoomInState(state, informinformBy2d){//是否点击后可放大
@@ -688,16 +608,7 @@ class PanoEditor extends THREE.EventDispatcher{
         if(!floor.panosBound){ 
             if(floor.panos.length == 0){
                 floor.panosBound = viewer.images360.bound.bounding.clone()
-            }else{ 
-                /* floor.panosBound = new THREE.Box3
-                
-                floor.panos.forEach(pano=>{
-                    floor.panosBound.expandByPoint(pano.position)
-                }) 
-                let center = floor.panosBound.getCenter(new THREE.Vector3)
-                let minBound = (new THREE.Box3()).setFromCenterAndSize(center, new THREE.Vector3(5,5,5))
-                floor.panosBound.union(minBound) */
-                
+            }else{  
                 let minSize = new THREE.Vector3(5,5,5)
                 let bound = math.getBoundByPoints(floor.panos.map(e=>e.position), minSize)
                 floor.panosBound = bound.bounding
@@ -786,7 +697,7 @@ class PanoEditor extends THREE.EventDispatcher{
             if(this.selectedLine){
                 this.selectedLine.dispatchEvent('click')//删除 
             } 
-            if(this.selectedPano){
+            if(this.selectedPano && clickPanoToLink){
                 this.selectedPano.circle.dispatchEvent('click')//删除 
             }
         }
@@ -1052,12 +963,12 @@ class PanoEditor extends THREE.EventDispatcher{
             circle.addEventListener('click', ()=>{ 
                 //if(this.activeViewName == 'mainView')return
                 if(this.clickToZoomInEnabled)return
-                if(this.operation == 'removeLink'){ 
+                if(clickPanoToLink && this.operation == 'removeLink'){ 
                     this.linkChange(pano, null, 'remove')  //删除所有连接
                 } 
                 
                 if(this.selectedPano == circle.pano) return this.selectPano(null)
-                if(this.operation == 'addLink' && this.selectedPano){
+                if(clickPanoToLink && this.operation == 'addLink' && this.selectedPano){
                     this.linkChange(this.selectedPano, circle.pano, 'add')
                     //this.setLinkOperateState('addLink',false)
                     return

+ 2 - 2
src/modules/siteModel/SiteModel.js

@@ -63,7 +63,7 @@ var SiteModel = {
         if(Potree.settings.isOfficial){
              
             viewer.addEventListener('camera_changed', e => {
-                if(e.changeInfo.positionChanged){
+                if(e.changeInfo && e.changeInfo.positionChanged){
                     this.updateEntityAt()
                 }
             })
@@ -1201,7 +1201,7 @@ var SiteModel = {
                 if(math.closeTo(position, viewer.images360.position)) return 'posNoChange'  
                 let size = boundingBox.getSize(new THREE.Vector3())
 
-            
+             
                 viewer.scene.view.setView({position,  duration})
                 viewer.mapViewer.moveTo(position, size, duration)  
             } 

+ 11 - 6
src/navigation/FirstPersonControls.js

@@ -68,7 +68,7 @@ export class FirstPersonControls extends THREE.EventDispatcher {
         //this.enableChangePos = true
         
         this.viewer.addEventListener('camera_changed',(e)=>{
-            this.setFPCMoveSpeed(e.viewport)
+            e.viewport && this.setFPCMoveSpeed(e.viewport)
         })
         
 
@@ -179,7 +179,7 @@ export class FirstPersonControls extends THREE.EventDispatcher {
                 } 
                 
                 if(camera.type == "OrthographicCamera"){
-                   
+                 
                     //console.log(e.drag.pointerDelta, e.pointer, e.drag.end)
                     let moveVec = Utils.getOrthoCameraMoveVec(e.drag.pointerDelta, camera )//最近一次移动向量
                   
@@ -200,9 +200,7 @@ export class FirstPersonControls extends THREE.EventDispatcher {
                                     let centerCloud = PanoEditor.selectedPano.pointcloud //选中的漫游点为旋转中心
                                     //pointclouds = PanoEditor.selectedClouds
                                     pointclouds = [centerCloud, ...PanoEditor.selectedClouds.filter(e=>e!=centerCloud)]//旋转中心点云放第一个
-                                    if(handleState == 'translate' && PanoEditor.activeViewName == 'right'){
-                                        moveVec.x = moveVec.y = 0  //只能上下移动
-                                    }  
+                                     
                                 }  
                             }else{
                                 PanoEditor.dispatchEvent('needToDisConnect')
@@ -227,7 +225,14 @@ export class FirstPersonControls extends THREE.EventDispatcher {
                         //}
                         
                     }
-                      
+                    
+
+                    if(handleState == 'translate' && viewport.alignment.translateVec){//只能沿某个方向移动
+                        moveVec.projectOnVector(viewport.alignment.translateVec)
+                    }
+                     
+
+                    
                     if(pointclouds){
                         this.dispatchEvent({
                             type : "transformPointcloud", 

+ 5 - 1
src/objects/Reticule.js

@@ -13,12 +13,13 @@ let defaultOpacity =  0.7
 export default class Reticule extends THREE.Mesh{
     constructor(viewer){
         var defaultTex = texLoader.load(Potree.resourcePath+'/textures/whiteCircle.png'/* reticule-256x256.png'  */)  
+        
         super(new THREE.PlaneBufferGeometry(0.11,0.11,1,1),new THREE.MeshBasicMaterial({
             side: THREE.DoubleSide , 
             map: defaultTex,
             transparent:true,
             depthTest: !1,
-            opacity: defaultOpacity,
+            opacity: defaultOpacity, 
             //depthWrite: !1,
         })) 
         this.name = 'reticule'
@@ -26,6 +27,9 @@ export default class Reticule extends THREE.Mesh{
         this.crosshairTex = texLoader.load(Potree.resourcePath+'/textures/reticule_cross_hair.png') 
         this.forbitTex = texLoader.load(Potree.resourcePath+'/textures/pic-forbid.png') 
         
+        this.defaultTex.anisotropy = 4 
+        this.crosshairTex.anisotropy = 4 
+        this.forbitTex.anisotropy = 4 
         //this.layers.set(0/* RenderLayers.RETICULE */);
         this.renderOrder = 100
         this.layers.set(Potree.config.renderLayers.marker);

+ 1 - 1
src/objects/Sprite.js

@@ -6,7 +6,7 @@ const geo = new THREE.PlaneBufferGeometry(1,1)
 export default class Sprite extends THREE.Mesh{
     
     constructor(options){  
-        super(geo, options.mat || new DepthBasicMaterial({map:options.map, useDepth:options.useDepth}))
+        super(geo, options.mat || new DepthBasicMaterial(options))/* ({map:options.map, useDepth:options.useDepth})) */
          
         this.root = options.root || this;
         this.renderOrder = options.renderOrder != void 0 ? options.renderOrder : 4;

+ 22 - 15
src/start.js

@@ -55,7 +55,17 @@ var start = function(dom, mapDom, number ){ //t-Zvd3w0m
         var pointcloudLoaded = 0
         var panosLoaded = 0
         var pointcloudLoadDone = function(){//点云cloud.js加载完毕后 
-            viewer.updateModelBound()
+             
+        }
+        
+         
+        var panosLoadDone = function(){   
+             
+            viewer.images360.loadDone() 
+            viewer.scene.add360Images(viewer.images360); 
+            viewer.mapViewer.addListener(viewer.images360)
+            
+            viewer.updateModelBound() //需等pano加载完
             let {boundSize, center} = viewer.bound
            
             Potree.Log(`中心点: ${math.toPrecision(center.toArray(),2)}, boundSize: ${math.toPrecision(boundSize.toArray(),2)} ` , null, 12)
@@ -80,16 +90,6 @@ var start = function(dom, mapDom, number ){ //t-Zvd3w0m
                 Potree.Log('loadPointCloudDone  点云加载完毕', null, 10)  
             }    
             
-        }
-        
-        
-        var panosLoadDone = function(){   
-            
-            
-            viewer.images360.loadDone() 
-            viewer.scene.add360Images(viewer.images360); 
-            viewer.mapViewer.addListener(viewer.images360)
-            
             
             {//初始位置 
                 var urlFirstView = false
@@ -632,8 +632,8 @@ var mergeEditStart = function(dom){
                 model.renderOrder = Potree.config.renderOrders.model;  //same as glb
             }
             
-            
-            /* {//transform --------维持离地高度和中心点的版本
+            if(Potree.settings.maintainBtmZ) 
+            {//transform --------维持离地高度和中心点的版本(local ver)
                 let updateBound = ()=>{ 
                     model.updateMatrixWorld()
                     viewer.updateModelBound() 
@@ -661,7 +661,7 @@ var mergeEditStart = function(dom){
                     MergeEditor.modelTransformCallback(model)
                 })
                 //离地高度只是boundingbox在transform后的最低点的高度,而非模型transform后的最低点的高度,所以旋转过后看起来不太准确
-            } */
+            } else
             
             {//transform --------维持中心点的版本
                 let updateBound = ()=>{ 
@@ -823,7 +823,14 @@ var mergeEditStart = function(dom){
  
  
  
- 
+window.testCubeGeo = function(state){
+    if(state === false){
+        return viewer.images360.cube.material.wireframe = false
+    }
+    viewer.images360.cube.material.wireframe = true
+    viewer.images360.cube.visible = true
+    Potree.settings.rotAroundPoint = false
+}
  
  
  

+ 2 - 2
src/utils.js

@@ -1187,7 +1187,7 @@ Utils.computePointcloudsBound = function(pointclouds){
     var boundingBox = new THREE.Box3();
     pointclouds.forEach(pointcloud=>{
         pointcloud.updateBound()
-        boundingBox.union(pointcloud.bound)
+        boundingBox.union(pointcloud.bound2)
     })
     var boundSize = boundingBox.getSize(new THREE.Vector3)
     var center = boundingBox.getCenter(new THREE.Vector3)
@@ -1402,7 +1402,7 @@ Utils.getIntersect = function (camera, meshes, pointer, raycaster) {
     } 
     
     meshes.forEach(e=>{ 
-        raycaster.layers.enable(math.getBaseLog(e.layers.mask,2)) 
+        raycaster.layers.enable(math.getBaseLog(2, e.layers.mask)) 
     }) 
     var n = raycaster.intersectObjects(meshes)
     if (0 === n.length) return null

+ 2 - 1
src/viewer/View.js

@@ -256,7 +256,7 @@ export class View extends THREE.EventDispatcher{
 		let startQuaternion, endQuaternion, endTarget = null ;
          
         
-		if(info.target ){
+		if(info.target && !info.target.equals(endPosition)){ //注:若target和position相同,没有意义,算出来的quaternion和最后lookAt(target)的效果不同,所以不使用
 			endTarget = new THREE.Vector3().copy(info.target)  
             endQuaternion = math.getQuaFromPosAim(endPosition,endTarget) 
 		}else if(info.quaternion){
@@ -345,6 +345,7 @@ export class View extends THREE.EventDispatcher{
                     
                     camera.zoom = endZoom * progress + startZoom * (1 - progress)
                     camera.updateProjectionMatrix() 
+                    //console.log('resolution',viewport.resolution.x,viewport.resolution.y,camera.zoom)
                 } 
             },
             

+ 32 - 8
src/viewer/viewer.js

@@ -76,7 +76,8 @@ import RenderPass from '../materials/postprocessing/RenderPass.js'
 import FXAAShader from "../materials/postprocessing/FXAAShader.js"
 import OutlinePass from "../materials/postprocessing/OutlinePass.js"
  
- 
+import Sprite from '../objects/Sprite.js' 
+import {TextSprite} from '../objects/TextSprite.js' 
 //import {RoomEnvironment} from './RoomEnvironment.js'
 
 import BasicMaterial from '../materials/BasicMaterial.js' 
@@ -88,6 +89,10 @@ let loaders = {}
 
 let mapArea; 
 let blockedByIntersectHistory = new Map();
+let texLoader = new THREE.TextureLoader()  
+
+
+ 
 export class Viewer extends ViewerBase{
 	
 	constructor(domElement, mapArea_, args = {}){
@@ -186,7 +191,7 @@ export class Viewer extends ViewerBase{
                     let potreeDescription = $(`<div id="potree_description" class="potree_info_text"></div>`);
                     $(domElement).append(potreeDescription);
                 }
-
+ 
                 if ($(domElement).find('#potree_annotations').length === 0) {
                     let potreeAnnotationContainer = $(`
                         <div id="potree_annotation_container" 
@@ -3947,7 +3952,10 @@ export class Viewer extends ViewerBase{
                  
                 viewer.scene.view.setView({position,  target, duration })
                
-                o.dontMoveMap || viewer.mapViewer.moveTo(position.clone(), null , duration)
+               
+                o.dontMoveMap || viewer.mapViewer.fitToPointcloud(pointcloud, duration)
+               
+                //o.dontMoveMap || viewer.mapViewer.moveTo(position.clone(), null , duration)
             }  
         }            
         
@@ -4190,16 +4198,20 @@ export class Viewer extends ViewerBase{
         }) 
         1 === this.waitQueue.length && this.dispatchEvent({type:"loading", show:true})
     }
-    ifAllLoaded(object){
+    ifAllLoaded(/* object */){
         if(this.waitQueue.length>0){
             this.waitQueue = this.waitQueue.filter(function(e) {
                 return !e.isLoadedCallback()
             })  
-        }
-       
+        } 
         0 === this.waitQueue.length && this.dispatchEvent({type:"loading", show:false}) 
     } 
-    
+    cancelLoad(object){//add 突然出现还没加载完就被deactivateTiledPano但还在loading的情况,所以加了这个
+        this.waitQueue = this.waitQueue.filter(function(e) {
+            return  e.object != object
+        })  
+        this.ifAllLoaded()
+    }
     
     setView(o={}){
         let callback = ()=>{
@@ -5032,7 +5044,19 @@ export class Viewer extends ViewerBase{
         */
     }
     
-    
+    addSprite(e){
+        let sprite 
+        
+        if(e.text != void 0){
+            sprite = new TextSprite(e )
+        }else{
+            let map = texLoader.load(src)
+            e.map = map
+            sprite = new Sprite(e )
+        }
+        
+        return sprite  
+    }
     
     
 };

+ 6 - 3
改bug的历史.txt

@@ -1,9 +1,12 @@
 
 
 
-
-
-
+2022.10.18
+接入bim时不知咋的出现一个bug,新加载的容易一直loading,当前漫游点isLoaded一直false,
+panoRenderer.panoLODDescriptors一直空的,uploadTile 只加载到第一个点(非当前pano)的部分
+接着发现是因为deactivateTiledPano了之后使该pano下载的图得不到下载成功的回调,而pano还一直存在waitQueue中
+所以增加cancelLoad函数,将其取消。
+(出现情况应该是切换pano过于快速)
 
 
 2022.8.30