Ver código fonte

fix: clip的改进了些

xzw 2 anos atrás
pai
commit
e66aa67436

+ 7 - 3
src/PotreeRendererNew.js

@@ -1120,6 +1120,7 @@ export class Renderer {
                 let numSnapshots = material.snapEnabled ? material.numSnapshots : 0;
                 let num_in_clipboxes = (material.clipBoxes_in && material.clipBoxes_in.length) ? material.clipBoxes_in.length : 0;
                 let num_out_clipboxes = (material.clipBoxes_out && material.clipBoxes_out.length) ? material.clipBoxes_out.length : 0;
+                let num_highlightBox = (material.highlightBoxes && material.highlightBoxes.length) ? material.highlightBoxes.length : 0;
                 let numClipSpheres = (params.clipSpheres && params.clipSpheres.length) ? params.clipSpheres.length : 0;
                 let numClipPolygons = (material.clipPolygons && material.clipPolygons.length) ? material.clipPolygons.length : 0;
 
@@ -1128,6 +1129,7 @@ export class Renderer {
                     `#define num_snapshots ${numSnapshots}`,
                     `#define num_in_clipboxes ${num_in_clipboxes}`, //改
                     `#define num_out_clipboxes ${num_out_clipboxes}`,   //改  
+                    `#define num_highlightBox ${num_highlightBox}`,   //改  
                     `#define num_clipspheres ${numClipSpheres}`, 
                 ];
                     
@@ -1320,11 +1322,13 @@ export class Renderer {
                 const lClipBoxes2 = shader.uniformLocations["clipBoxes_out[0]"];
 				gl.uniformMatrix4fv(lClipBoxes2, false, material.uniforms.clipBoxes_out.value); 
             }
+            if (material.highlightBoxes && material.highlightBoxes.length > 0) {//add 
+                const boxes_highlight = shader.uniformLocations["boxes_highlight[0]"];
+                gl.uniformMatrix4fv(boxes_highlight, false, material.uniforms.boxes_highlight.value);  
+            }
             if (material.bigClipInBox ) {//add 
-				shader.setUniformMatrix4("clipBoxBig_in", material.uniforms.clipBoxBig_in.value);
-                
+				shader.setUniformMatrix4("clipBoxBig_in", material.uniforms.clipBoxBig_in.value); 
             }
-                
 
 			// TODO CLIPSPHERES
 			if(params.clipSpheres && params.clipSpheres.length > 0){

+ 37 - 9
src/custom/modules/clipModel/Clip.js

@@ -6,13 +6,15 @@ import Common from '../../utils/Common.js'
 import math from '../../utils/math.js' 
 import {Images360} from '../panos/Images360.js'  
 
-const defaultBoxWidth = 6;  //navvis:  10
+const defaultBoxWidth = 16;  //navvis:  10
                             //navvis position: si {x: 0, y: 0, z: 0}
    
 var Clip = {
     bus : new THREE.EventDispatcher,
     selectedDatasets : [],    
     changeCallback(force){ 
+        viewer.controls.setTarget(this.box.position)//绕其旋转
+        
         if(Potree.settings.isOfficial){  
             Common.intervalTool.isWaiting('clipSelectedDatasets', ()=>{ //延时update,防止卡顿
                 let pointclouds = this.getIntersectPointcloud() 
@@ -24,7 +26,7 @@ var Clip = {
                     return true 
                 } 
             },  300)  
-        } 
+        }  
     },
 
     enter:function(){
@@ -56,7 +58,7 @@ var Clip = {
             callback:function(){ 
             }
         })
-        viewer.setControls(viewer.orbitControls);
+        //viewer.setControls(viewer.orbitControls);
         viewer.setLimitFar(false) 
         //viewer.setClipState(false) //暂时关闭旧的clipping
         
@@ -139,7 +141,8 @@ var Clip = {
         viewer.transformationTool.frame.material.color.set(Potree.config.clip.color)//navvis 15899953 
         viewer.setPointStandardMat(true) 
         
-        {
+        { 
+            let mapVisi = false
             this.events = {
                 flyToPos : (e)=>{ 
                     let dis = 2
@@ -158,10 +161,33 @@ var Clip = {
                     
                     let duration = 1000
                     viewer.scene.view.setView({position,  duration,  target})
-                } 
+                     
+                },
+                mapVisiChange(e){
+                    mapVisi = e.visible
+                    let delay =  100  //因resize了camera需要时间更新projectionMatrix
+                    setTimeout(()=>{
+                        let boundingBox = Clip.box.boundingBox.clone().applyMatrix4(Clip.box.matrixWorld)
+                        if(mapVisi){//切换地图
+                            if(Clip.switchMapCount == 0 || !Potree.Utils.isInsideFrustum(boundingBox, viewer.mapViewer.camera)){ 
+                                let size = boundingBox.getSize(new THREE.Vector3)
+                                let margin = viewer.mainViewport.resolution.clone().multiplyScalar(0.3) 
+                                viewer.mapViewer.moveTo(Clip.box.position, size, 100, margin)   
+                            }
+                            Clip.switchMapCount++
+                            //关于究竟是focus box还是dataset有点纠结,又或是两个的union。box和数据集可能离得很远,且无法确定当前想选择的数据集,且数据集可能无floorplan, 即使有可能也不展示……
+                        }else{//切换3d
+                            if(!Potree.Utils.isInsideFrustum(boundingBox, viewer.scene.getActiveCamera())){//屏幕上没有box的话
+                                viewer.focusOnObject({boundingBox}, 'boundingBox', 100  )
+                            }
+                        }      
+                    },delay) 
+                     
+                }
             }
-            
+            this.switchMapCount = 0
             this.bus.addEventListener('flyToPos',this.events.flyToPos) 
+            viewer.mapViewer.addEventListener('forceVisible',this.events.mapVisiChange) 
         }
         this.editing = true
         
@@ -173,7 +199,7 @@ var Clip = {
         viewer.scene.removeVolume(this.box);
         
         this.mapBox.dispose()
-        viewer.setControls(viewer.fpControls);
+        //viewer.setControls(viewer.fpControls);
         
         Potree.settings.unableNavigate = false
         Potree.settings.ifShowMarker = this.previousView.ifShowMarker
@@ -183,9 +209,11 @@ var Clip = {
         viewer.setLimitFar(true)
         viewer.setPointStandardMat(false) 
         //viewer.setClipState(true)
-        
+        viewer.controls.setTarget(null)
         {
             this.bus.removeEventListener('flyToPos',this.events.flyToPos) 
+            viewer.mapViewer.removeEventListener('forceVisible',this.events.mapVisiChange) 
+            
             this.events = null 
         }
         this.editing = false
@@ -240,7 +268,7 @@ var Clip = {
                 let data = {
                     id: cloud.dataset_id, 
                     matrix : this.getTransformationMatrix(cloud).elements, //剪裁大框
-                    VisiMatrixes: cloud.material.clipBoxes_in.map(e=>this.getTransformationMatrix(cloud, e.inverse).elements), //若干个可见型小框
+                    VisiMatrixes: cloud.material.clipBoxes_in.map(e=>this.getTransformationMatrix(cloud, e.inverse).elements), //若干个可见型小框(虽然现在用不到了,因为普通界面不展示这些剪裁区域)
                     UnVisiMatrixes: cloud.material.clipBoxes_out.map(e=>this.getTransformationMatrix(cloud, e.inverse).elements), //若干个不可见型小框
                     modelMatrix:(new THREE.Matrix4).copy(cloud.transformMatrix).transpose().elements
                 }  

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

@@ -141,8 +141,8 @@ var Alignment = {
                     }else{ 
                         let vec = new THREE.Vector3().subVectors(e.intersect, center).setZ(0)
                         let angle = math.getAngle(transfromInfo.vecStart,vec,'z')   
-                        let diffAngle = transfromInfo.orientationUser + angle - transfromInfo.pointcloud[0].orientationUser
-                        Alignment.rotate(transfromInfo.pointcloud[0], null, diffAngle)
+                        let diffAngle = transfromInfo.orientationUser + angle - transfromInfo.pointclouds[0].orientationUser
+                        Alignment.rotate(transfromInfo.pointclouds[0], null, diffAngle)
                     }
                 }    
             } 

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

@@ -655,7 +655,7 @@ export class Images360 extends THREE.EventDispatcher{
             toPano = {pano: toPano}
         }
         
-        if(!toPano.pano.enabled)return
+        
   
         /* if(!this.currentPano){
             return this.focusPano(toPano) 
@@ -676,6 +676,10 @@ export class Images360 extends THREE.EventDispatcher{
             //this.dispatchEvent('cameraMoveDone')
             toPano.deferred && toPano.deferred.resolve(makeIt)  //测量线截图时发现,resolve需要写在flying=false 后才行。
         }
+        
+        if(!toPano.pano.enabled)return done(false,true);
+        
+        
         if(this.currentPano == toPano.pano && this.isAtPano() && !toPano.target && !toPano.quaternion  ){
             this.dispatchEvent({type:'flyToPano', toPano})
             return done(true);

+ 1 - 1
src/custom/modules/panos/tile/TileDownloader.js

@@ -452,7 +452,7 @@ TileDownloader.prototype.getTileUrl = function() {
             tileSize = o.tileSize,
             tileIndex = o.tileIndex,
             sceneCode = o.pano.pointcloud.sceneCode,
-            useV4url = Potree.settings.testV4url /* && o.pano.pointcloud.useV4url */     //v4的全景图等路径不一样  
+            useV4url = Potree.settings.testV4url && o.pano.pointcloud.datasetData.sceneVersion == 'V4'        //v4的全景图等路径不一样  
         var metadata = {sceneScheme:10}  
         
         

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

@@ -1205,10 +1205,9 @@ var SiteModel = {
                 let size = boundingBox.getSize(new THREE.Vector3())
 
              
-                viewer.scene.view.setView({position,  duration})
-                viewer.mapViewer.moveTo(position, size, duration)  
+                viewer.scene.view.setView({position,  duration}) 
             } 
-            
+            viewer.mapViewer.moveTo(position, size, duration)  
         }
         return true
     },

+ 2 - 2
src/custom/objects/tool/Measure.js

@@ -657,7 +657,7 @@ export class Measure extends ctrlPolygon{
                 this.setSelected(false, 'edgeLabel')
             })  
             edgeLabel.addEventListener('click',()=>{
-                viewer.focusOnObject(this, 'measure')
+                this.isNew || viewer.focusOnObject(this, 'measure')
             })
         }
         edgeLabel.visible = false
@@ -691,7 +691,7 @@ export class Measure extends ctrlPolygon{
             this.setSelected(false, 'areaLabel')
         }) 
         areaLabel.addEventListener('click',()=>{
-            viewer.focusOnObject(this, 'measure')
+            this.isNew || viewer.focusOnObject(this, 'measure')
         })
         viewer.setObjectLayers(areaLabel, 'measure' )
         areaLabel.visible = false

+ 6 - 4
src/custom/objects/tool/MeasuringTool.js

@@ -388,10 +388,10 @@ export class MeasuringTool extends THREE.EventDispatcher{
 		};
 
 		let end = (e={}) => {//确定、结束
-            if(!measure.isNew)return
-            if(args.minMarkers != void 0){
+            if(!measure.isNew ||  measure.markers.length == 0)return
+            if(args.minMarkers != void 0 ){
                 
-                if(!e.finish && measure.markers.length<=args.minMarkers){//右键  当个数不够时取消
+                if(!e.finish && measure.markers.length<=args.minMarkers ){//右键  当个数不够时取消
                     //this.viewer.scene.removeMeasurement(measure)
                     //cancelFun && cancelFun()
                     //重新开始画
@@ -452,6 +452,8 @@ export class MeasuringTool extends THREE.EventDispatcher{
             }); */
 		};
 
+        measure.addEventListener('finish', end) //完成
+        
         
         let Exit = (e)=>{//强制退出
         
@@ -486,7 +488,7 @@ export class MeasuringTool extends THREE.EventDispatcher{
         
         
         this.viewer.addEventListener('cancel_insertions', Exit);
-        
+         
         /*let pressExit
          if(!Potree.settings.isOfficial){
             pressExit = (e)=>{ 

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

@@ -341,7 +341,7 @@ export class ctrlPolygon extends THREE.Object3D {
                 } */
                 this.getPoint2dInfo(points)
                 
-                var isIntersectSelf = this.atPlane && !this.isRect && len > 3 && this.intersectSelf(this.point2dInfo.points2d)//检测相交
+                var isIntersectSelf = this.atPlane && this.closed && !this.isRect && this.intersectSelf(this.point2dInfo.points2d)//检测相交
                 if(isIntersectSelf){
                     //not-allowed
                     viewer.dispatchEvent({

+ 7 - 4
src/custom/objects/tool/mapClipBox.js

@@ -11,10 +11,13 @@ let texLoader = new THREE.TextureLoader()
 let color = new THREE.Color(config.clip.color)
 
 let markerMats
-let markerSizeInfo = {width2d:30}
-
+let markerSizeInfo = {width2d: 40}
 
 
+const pickOrders = {
+    marker:1,
+    area: 0,
+}
 
 export class mapClipBox extends ctrlPolygon {
     constructor (center, scale) { 
@@ -95,13 +98,13 @@ export class mapClipBox extends ctrlPolygon {
    
     
     addMarker(o={} ){
-        let marker = new Sprite({mat:this.getMarkerMaterial('default'), sizeInfo: markerSizeInfo, dontFixOrient: true, viewports:viewer.mapViewer.viewports, name:"mapClipBox_marker",   } )
+        let marker = new Sprite({mat:this.getMarkerMaterial('default'), pickOrder:pickOrders.marker, sizeInfo: markerSizeInfo, dontFixOrient: true, viewports:viewer.mapViewer.viewports, name:"mapClipBox_marker",   } )
         
         marker.renderOrder = 3 
         //marker.markerSelectStates = {}
         
         let edge = LineDraw.createLine([new THREE.Vector3,new THREE.Vector3],{color  })
-        let edgeMarker = new Sprite({mat:this.getMarkerMaterial('default'), sizeInfo: markerSizeInfo, dontFixOrient: true, viewports:viewer.mapViewer.viewports, name:"mapClipBox_edgePoint"} )
+        let edgeMarker = new Sprite({mat:this.getMarkerMaterial('default'),  pickOrder:pickOrders.marker, sizeInfo: markerSizeInfo, dontFixOrient: true, viewports:viewer.mapViewer.viewports, name:"mapClipBox_edgePoint"} )
         let mouseover = (e) => {
             this.setMarkerSelected(e.object, true, 'single');
             viewer.dispatchEvent({

+ 52 - 28
src/custom/potree.shim.js

@@ -252,7 +252,7 @@ Utils.getMousePointCloudIntersection = function(viewport, mouse, pointer, camera
     let old_clipBoxes_in = new Map()  
     let old_clipBoxes_out = new Map()  
     let old_bigClipInBox = new Map()  
-     
+    let old_highlightBoxes = new Map()   
     
     //bigClipInBox 最好也写下 
     let density
@@ -289,7 +289,8 @@ Utils.getMousePointCloudIntersection = function(viewport, mouse, pointer, camera
             old_clipBoxes_in.set(pointcloud, pointcloud.clipBoxes_in)
             old_clipBoxes_out.set(pointcloud, pointcloud.clipBoxes_in)
             old_bigClipInBox.set(pointcloud, pointcloud.bigClipInBox)
-            pointcloud.material.setClipBoxes(null, [],[])  
+            old_highlightBoxes.set(pointcloud, pointcloud.highlightBoxes)
+            pointcloud.material.setClipBoxes(null, [],[],[])  
         }
         needsUpdate = true
     }
@@ -341,7 +342,7 @@ Utils.getMousePointCloudIntersection = function(viewport, mouse, pointer, camera
     }
     if(!pickParams.pickClipped){//add  
         for(let pointcloud of pointclouds){  
-            pointcloud.material.setClipBoxes(old_bigClipInBox.get(pointcloud), old_clipBoxes_in.get(pointcloud), old_clipBoxes_out.get(pointcloud))  
+            pointcloud.material.setClipBoxes(old_bigClipInBox.get(pointcloud), old_clipBoxes_in.get(pointcloud), old_clipBoxes_out.get(pointcloud), old_highlightBoxes.get(pointcloud))  
         } 
     }
 
@@ -1691,19 +1692,19 @@ VolumeTool.prototype.update = function(){}
 
 VolumeTool.prototype.startInsertion = function(args = {}){
     
-    let volume;
+    let volume; 
+    let camera = this.viewer.scene.getActiveCamera();
     if(args.type){
         volume = new args.type();
     }else{
-        volume = new Potree.BoxVolume(args/* {clip:args.clip, clipTask:ClipTask.SHOW_OUTSIDE} */);
+        volume = new Potree.BoxVolume(Object.assign(args,{clip:true}) );
     }
-      
-    volume.name = args.name || 'Volume';
+    volume.highlight = true  
+    volume.name = args.name || 'Volume-'+args.clipTask;
     volume.isNew = true
-      
+    viewer.transformObject(null)//先清空
     
-    let camera = this.viewer.scene.getActiveCamera();
-    let updateScale = ()=>{ //保证在视野中的大小一致: 
+    let updatePose = ()=>{ //保证在视野中的大小一致: 
         let w = math.getScaleForConstantSize({
             width2d: 300,
             camera , position:volume.getWorldPosition(new THREE.Vector3()) ,
@@ -1712,18 +1713,21 @@ VolumeTool.prototype.startInsertion = function(args = {}){
         /* let wp = volume.getWorldPosition(new THREE.Vector3()).applyMatrix4(camera.matrixWorldInverse);
         // let pp = new THREE.Vector4(wp.x, wp.y, wp.z).applyMatrix4(camera.projectionMatrix);
         let w = Math.abs((wp.z / 3));*/
-        if(!isNaN(w))volume.scale.set(w, w, w);  
+        if(!isNaN(w))volume.scale.set(w,  w,  w); 
+        
+        
+        {//使水平朝向与camera一致
+            let direction = viewer.mainViewport.view.direction.setZ(0) 
+            volume.quaternion.copy(math.getQuaByAim(direction)) 
+        }
+        
     }
 
     this.dispatchEvent({
         type: 'start_inserting_volume',
         volume: volume
-    });
-    
-    /* if(viewer.scene.volumes.length>0){
-        volume.rotation.copy(viewer.scene.volumes[viewer.scene.volumes.length-1].rotation); //使用上一个的旋转值
-    } */
-    updateScale()
+    }); 
+    updatePose()
     this.viewer.scene.addVolume(volume);
     this.scene.add(volume);
     
@@ -1749,32 +1753,52 @@ VolumeTool.prototype.startInsertion = function(args = {}){
              
         volume.position.copy(worldPos);
         
-        updateScale() 
+        updatePose() 
     };
+     
     
-    let cancel = ()=>{
-        viewer.scene.removeVolume(volume);  //删除没完成的
-        end('remove') 
+    
+    
+    let cancel = ()=>{ 
+        end('remove')  
     }
     let end = (e) => {
-        if(e != 'remove' && !e.isAtDomElement)return
+        if(e.button == THREE.MOUSE.RIGHT && e.pressDistance<=Potree.config.clickMaxDragDis) {//remove
+            e = 'remove'
+        } 
+        if(e != 'remove' && (!e.isAtDomElement || e.pressDistance>Potree.config.clickMaxDragDis))return continueDrag()
         volume.removeEventListener('drag', drag);
         volume.removeEventListener('drop', end);
         this.viewer.removeEventListener('cancel_insertions', cancel);
         volume.isNew = false
-        if(e != 'remove'){
-            viewer.transformObject(volume)
-            volume.dispatchEvent('createDone')
-            
+        viewer.removeEventListener('camera_changed',  updatePose)
+        if(e == 'remove'){
+            viewer.scene.removeVolume(volume);  //删除没完成的
+        }else{
+            viewer.transformObject(volume)  
+            volume.highlight = false
+          
         }
+        
+        volume.dispatchEvent({type:'createFinish', success:e != 'remove'})
     };
+     
+    let continueDrag = ( )=>{ 
+        var timer = setTimeout(()=>{//等 drag=null之后 //右键拖拽结束后需要重新得到drag  
+            viewer.inputHandler.startDragging( volume  ,  {notPressMouse:true}
+               /*  {endDragFun: e.drag.endDragFun, notPressMouse:e.drag.notPressMouse, dragViewport:e.drag.dragViewport}  */
+            ) 
+        },1)
+        return timer
+    }
     
     volume.addEventListener('drag', drag);
     volume.addEventListener('drop', end);
     
     this.viewer.addEventListener('cancel_insertions', cancel);
-
-    this.viewer.inputHandler.startDragging(volume);
+    viewer.addEventListener('camera_changed',  updatePose)
+    
+    this.viewer.inputHandler.startDragging(volume,  {notPressMouse:true});
     
     return volume;
 }

+ 1 - 1
src/custom/settings.js

@@ -438,7 +438,7 @@ let settings = {//设置   可修改
     precision:2,  // 两位小数
     
     
-    testV4url:false, //v4的全景图等路径不一样 scene_view_data
+    testV4url:true, //v4的全景图等路径不一样 scene_view_data
     
     
     //testCube:true,

+ 2 - 0
src/custom/start.js

@@ -185,6 +185,8 @@ export function start(dom, mapDom, number ){ //t-Zvd3w0m
                     let config = Potree.config.material
                     let material = pointcloud.material; 
                     
+                    
+                    pointcloud.datasetData = dataset
                     pointcloud.hasDepthTex = Potree.settings.useDepthTex && (!!dataset.has_depth  ||  Potree.settings.isLocalhost && Potree.settings.number == 'SS-t-7DUfWAUZ3V') //test   
                     material.minSize =  config.minSize
                     material.maxSize =  config.maxSize   

+ 16 - 4
src/custom/utils/math.js

@@ -398,8 +398,8 @@ var math = {
             return new THREE.Quaternion().setFromAxisAngle( upVec, angle );
         }
         return new THREE.Quaternion().setFromAxisAngle( axis, angle );
-    }
-    /* ,
+    } ,
+    /*
     getQuaBetween2Vector2 : function(oriVec, newVec   ){//not camera
         var _ = (new THREE.Matrix4).lookAt( oriVec, new THREE.Vector3, new THREE.Vector3(0,1,0))
         var aimQua = (new THREE.Quaternion).setFromRotationMatrix(_)
@@ -410,8 +410,20 @@ var math = {
         
     } */
     
-        
-    ,
+    getQuaByAim: function (aim, center=new THREE.Vector3) { 
+        let forward = new THREE.Vector3(0, 1, 0)
+        let qua1 = new THREE.Quaternion().setFromUnitVectors(forward, aim.clone().sub(center).normalize())
+        /*  var _ = (new THREE.Matrix4).lookAt(center,aim,   new THREE.Vector3(0,1,0));  
+        let qua2 = (new THREE.Quaternion).setFromRotationMatrix(_);
+        let rot1 = new THREE.Euler().setFromQuaternion(qua1)
+        let rot2 = new THREE.Euler().setFromQuaternion(qua2)  //奇怪,qua2怎么都不对
+        console.log(rot1,rot2) */
+        return qua1
+    },
+    getAimByQua: function (quaternion, center=new THREE.Vector3) {
+        return new THREE.Vector3(0, 0, -1).applyQuaternion(quaternion).add(center)
+    },    
+     
     
     getScaleForConstantSize : function(){ //获得规定二维大小的mesh的scale值。可以避免因camera的projection造成的mesh视觉大小改变。  来源:tag.updateDisc
         var w;  

+ 16 - 15
src/custom/viewer/ViewerNew.js

@@ -739,7 +739,10 @@ export class Viewer extends ViewerBase{
             //if(force || !currPos.equals(this.lastPos)){
                 //this.lastPos.copy(currPos)
                 
-                var at = this.scene.pointclouds.filter(e=>e.ifContainsPoint(currPos)) 
+                var at = this.scene.pointclouds.filter(e=>
+                    (e.visible || e.unvisibleReasons && e.unvisibleReasons.length == 1 && e.unvisibleReasons[0].reason == 'displayMode')
+                    && e.ifContainsPoint(currPos)
+                ) 
                 
                 if(Common.getDifferenceSet(at, this.atDatasets).length){
                     //console.log('atDatasets', at) 
@@ -2406,18 +2409,18 @@ export class Viewer extends ViewerBase{
 				return {box: box, inverse: boxInverse/* , position: boxPosition */};
 			});
             //改
-            let bigClipInBox = clipBoxes.find(e=>e.box.clipTask == ClipTask.SHOW_INSIDE_Big)//裁剪下载 when this.modules.Clip.editing
-            let clipBoxes_in = clipBoxes.filter(e=>e.box.clipTask == ClipTask.SHOW_INSIDE)
-            let clipBoxes_out = clipBoxes.filter(e=>e.box.clipTask == ClipTask.SHOW_OUTSIDE)
-   
-			// set clip volumes in material
+            let bigClipInBox = clipBoxes.find(e=>e.box.clipTask == ClipTask.SHOW_INSIDE_Big && !e.box.highlight)//裁剪下载 when this.modules.Clip.editing
+            let clipBoxes_in = clipBoxes.filter(e=>e.box.clipTask == ClipTask.SHOW_INSIDE && !e.box.highlight)
+            let clipBoxes_out = clipBoxes.filter(e=>e.box.clipTask == ClipTask.SHOW_OUTSIDE && !e.box.highlight)
+            let highlightBoxes = clipBoxes.filter(e=>e.box.highlight )
+			
+            // set clip volumes in material
 			for(let pointcloud of visiblePointClouds){
-                let clipBoxes_in2 = [], clipBoxes_out2 = []
+                let clipBoxes_in2 = [], clipBoxes_out2 = [], highlightBoxes2 = []
                 if(pointcloud.dataset_id == Potree.settings.originDatasetId){ //实时裁剪只对初始数据集有效
-                    clipBoxes_in2 = clipBoxes_in,  clipBoxes_out2 = clipBoxes_out
+                    clipBoxes_in2 = clipBoxes_in,  clipBoxes_out2 = clipBoxes_out, highlightBoxes2 = highlightBoxes
                 }
-				pointcloud.material.setClipBoxes(bigClipInBox, clipBoxes_in2, clipBoxes_out2); 
-				 
+				pointcloud.material.setClipBoxes(bigClipInBox, clipBoxes_in2, clipBoxes_out2, highlightBoxes2);  
 			}
 		}  
 
@@ -3868,11 +3871,9 @@ export class Viewer extends ViewerBase{
             }else{
                 if(math.closeTo(position, this.images360.position)) return 'posNoChange'
                  
-                viewer.scene.view.setView({position,  target, duration })
-                
-                o.dontMoveMap || viewer.mapViewer.fitToPointcloud(pointcloud, duration)
-                //o.dontMoveMap || viewer.mapViewer.moveTo(position.clone(), null , duration)
-            }  
+                viewer.scene.view.setView({position,  target, duration })   
+            }
+            o.dontMoveMap || viewer.mapViewer.fitToPointcloud(pointcloud, duration)            
         }            
         
         return true

+ 3 - 3
src/custom/viewer/map/MapViewer.js

@@ -145,7 +145,7 @@ export class MapViewer extends ViewerBase{
             }), toPano.duration, null, 0, easing[toPano.easeName]  );  */ 
             let boundSize// = new THREE.Vector2(10,10)
             
-            this.moveTo(toPano.pano.position.clone().setZ(Potree.config.map.cameraHeight),  boundSize, toPano.duration, toPano.easeName) 
+            this.moveTo(toPano.pano.position.clone().setZ(Potree.config.map.cameraHeight),  boundSize, toPano.duration, null, toPano.easeName) 
         })
         
         
@@ -396,9 +396,9 @@ export class MapViewer extends ViewerBase{
         this.moveTo(center, size, 200 ) //给duration是为了顺应视口大小改变,缓冲
     }
     
-    moveTo(endPosition, boundSize, duration=0, easeName){//前两个参数有xy即可
+    moveTo(endPosition, boundSize, duration=0, margin, easeName ){//前两个参数有xy即可
         endPosition = new THREE.Vector3(endPosition.x,endPosition.y,Potree.config.map.cameraHeight)
-        this.view.moveOrthoCamera(this.viewports[0],  {endPosition, boundSize },   duration,  easeName)
+        this.view.moveOrthoCamera(this.viewports[0],  {endPosition, boundSize, margin},   duration,  easeName)
         
        
         

+ 9 - 15
src/materials/ExtendPointCloudMaterial.js

@@ -51,6 +51,7 @@ export class ExtendPointCloudMaterial extends PointCloudMaterial {
             clipBoxes_in:  { type: "Matrix4fv", value: [] },
             clipBoxes_out:  { type: "Matrix4fv", value: [] },
             clipBoxBig_in:  { type: "Matrix4fv", value: [] },
+            boxes_highlight:  { type: "Matrix4fv", value: [] },
 			progress: {
 				type: "f",
 				value: 0
@@ -293,20 +294,9 @@ export class ExtendPointCloudMaterial extends PointCloudMaterial {
         this.usePanoMap = false
     } 
 
-	// copyFrom(from){
-
-	// 	var a = 10;
-
-	// 	for(let name of Object.keys(this.uniforms)){
-	// 		this.uniforms[name].value = from.uniforms[name].value;
-	// 	}
-	// }
-
-	// copy(from){
-	// 	this.copyFrom(from);
-	// }
+	 
     
-	setClipBoxes (bigClipInBox, clipBoxes_in,clipBoxes_out) {
+	setClipBoxes (bigClipInBox, clipBoxes_in,clipBoxes_out, highlightBoxes) {
 		if (!clipBoxes_in || !clipBoxes_out) {
 			return;
 		}
@@ -321,10 +311,11 @@ export class ExtendPointCloudMaterial extends PointCloudMaterial {
         this.bigClipInBox = bigClipInBox
         this.clipBoxes_in = clipBoxes_in
         this.clipBoxes_out = clipBoxes_out
+        this.highlightBoxes = highlightBoxes
 		this.uniforms.clipBoxBig_in.value = bigClipInBox && bigClipInBox.inverse
 		this.uniforms.clipBoxes_in.value = new Float32Array(this.clipBoxes_in.length * 16);
 		this.uniforms.clipBoxes_out.value = new Float32Array(this.clipBoxes_out.length * 16);
-        
+		this.uniforms.boxes_highlight.value = new Float32Array(this.highlightBoxes.length * 16);
         
 		for (let i = 0; i < this.clipBoxes_in.length; i++) {
 			let box = clipBoxes_in[i];  
@@ -334,7 +325,10 @@ export class ExtendPointCloudMaterial extends PointCloudMaterial {
 			let box = clipBoxes_out[i];  
 			this.uniforms.clipBoxes_out.value.set(box.inverse.elements, 16 * i);
 		}
-
+		for (let i = 0; i < this.highlightBoxes.length; i++) {
+			let box = highlightBoxes[i];  
+			this.uniforms.boxes_highlight.value.set(box.inverse.elements, 16 * i);
+		}
 
 
 		/* for (let i = 0; i < this.uniforms.clipBoxes.value.length; i++) {??

+ 20 - 2
src/materials/shaders/pointcloud_new.vs

@@ -102,7 +102,10 @@ uniform float uOrthoHeight;
 #endif
 
  
-
+#if defined(num_highlightBox) && num_highlightBox > 0
+    uniform mat4 boxes_highlight[num_highlightBox];   
+#endif        
+		 
 
 uniform float size;
 uniform float minSize;
@@ -848,7 +851,7 @@ void doClipping(){
             gl_Position = vec4(100.0, 100.0, 100.0, 1.0);
             return;;
         }  
-    #endif
+    #endif 
     
     #if defined(num_in_clipboxes) && num_in_clipboxes > 0
         //当有可见box时,需要在任一可见box内才可见
@@ -881,6 +884,21 @@ void doClipping(){
         }
 	#endif 
  
+ 
+    #if defined(num_highlightBox) && num_highlightBox > 0
+        //当有高亮box时,需要在任一可见高亮内都高宽
+        bool highlight = false;
+		for(int i = 0; i < num_highlightBox; i++){ 
+            if(insideBox(boxes_highlight[i])){
+                highlight = true;
+                break;
+            } 
+		}
+        if(highlight){
+            vColor.r += 0.5; 
+        }
+	#endif
+ 
 }
 
 

+ 12 - 6
src/navigation/FirstPersonControlsNew.js

@@ -302,7 +302,7 @@ export class FirstPersonControls extends THREE.EventDispatcher {
                             speed = FirstPersonControls.boundPlane.distanceToPoint(this.currentViewport.position)   
                             speed = Math.max(1 , speed) 
                         }  */
-                        let lastIntersect = viewport.lastIntersect && (viewport.lastIntersect.location || viewport.lastIntersect)//该viewport的最近一次鼠标和点云的交点
+                        let lastIntersect = this.target || viewport.lastIntersect && (viewport.lastIntersect.location || viewport.lastIntersect)//该viewport的最近一次鼠标和点云的交点
                         if(!lastIntersect || !(lastIntersect instanceof THREE.Vector3))lastIntersect = viewer.bound.center  
                         let speed = camera.position.distanceTo(lastIntersect)   
                         let fov = cameraLight.getHFOVForCamera(camera, true)
@@ -393,8 +393,12 @@ export class FirstPersonControls extends THREE.EventDispatcher {
                     speed =  this.currentViewport.getMoveSpeed() * 15
                     
                     //var direction = this.currentViewport.view.direction.clone();
-                    direction = this.viewer.inputHandler.getMouseDirection().direction  //定点缩放
-                 
+                    
+                    /* if(this.target && !e.intersect){//如果没有intersect点云且有target的话,就朝target的方向. 但无限靠近时有问题,且到背面时前进却是后退
+                        direction = new THREE.Vector3().subVectors(this.target, camera.position).normalize()
+                    }else{ */
+                        direction = this.viewer.inputHandler.getMouseDirection().direction  //定点缩放
+                    //}
                     
                     if(e.delta == 0){//mac
                         return 
@@ -457,8 +461,8 @@ export class FirstPersonControls extends THREE.EventDispatcher {
             let rotAroundPoint = Potree.settings.rotAroundPoint && e.dragViewport.camera.type != 'OrthographicCamera' &&  (viewer.atDatasets.length == 0 || intersect) && this.canMovePos(viewport) && !viewer.images360.isAtPano() && !this.viewer.inputHandler.pressedKeys[32]
             let rotCenter2d, rotCenter
             if(rotAroundPoint){
-                let pivotType = viewer.atDatasets.length > 0 ? 'intersect' :  viewer.inputHandler.selection.length ? 'selection' : 'boundCenter'  
-                rotCenter = pivotType == 'intersect' ? intersect.location : pivotType == 'selection' ? viewer.inputHandler.selection[0].position : viewer.bound.center
+                let pivotType = this.target ? 'target' : viewer.atDatasets.length > 0 ? 'intersect' :  viewer.inputHandler.selection.length ? 'selection' : 'boundCenter'  
+                rotCenter = pivotType == 'target'? this.target :pivotType == 'intersect' ? intersect.location : pivotType == 'selection' ? viewer.inputHandler.selection[0].position : viewer.bound.center
                 if(rotCenter){
                     rotCenter2d = rotCenter.clone().project(e.dragViewport.camera) //点在屏幕中的位置
                 }else{
@@ -530,7 +534,9 @@ export class FirstPersonControls extends THREE.EventDispatcher {
         this.enabled = enabled;
          
     }
-
+    setTarget(target){//绕该点旋转,类似orbitControl
+        this.target = target
+    }
     setFPCMoveSpeed(viewport){
         if(viewport.camera.type == 'OrthographicCamera'){
             let s = 1 / viewport.camera.zoom

+ 3 - 10
src/navigation/InputHandlerNew.js

@@ -296,14 +296,14 @@ export class InputHandler extends THREE.EventDispatcher {
 		if (this.logMessages) console.log(this.constructor.name + ': onKeyDown');
 
 		// DELETE
-		if (e.keyCode === KeyCodes.DELETE && this.selection.length > 0) {
+		/* if (e.keyCode === KeyCodes.DELETE && this.selection.length > 0) {
 			this.dispatchEvent({ 
 				type: 'delete',
 				selection: this.selection
 			});
 
 			this.deselectAll();
-		}
+		} */
 
 		this.dispatchEvent({
 			type: 'keydown',
@@ -620,14 +620,7 @@ export class InputHandler extends THREE.EventDispatcher {
 
                             if (selectable) {
                                 selectable = selectable.object;
-
-                                /* if (this.isSelected(selectable)) {
-                                    this.selection.filter(e => e !== selectable).forEach(e => this.toggleSelection(e)); 
-                                } else {
-                                    this.deselectAll();
-                                    this.toggleSelection(selectable);
-                                } */
-                                 
+  
                                 if (this.isSelected(selectable)) {
                                     this.deselectAll();
                                 } else {

+ 3 - 3
src/utils/TransformationToolNew.js

@@ -486,10 +486,10 @@ export class TransformationTool extends THREE.EventDispatcher{
     
     
 	initializeRotationHandles(){
-		let boldAdjust = 2;
+		let boldAdjust = 2.5;
 		let torusGeometry = new THREE.TorusGeometry(1.4, boldAdjust * 0.015, 8, 64, Math.PI / 2);
 		//let outlineGeometry = new THREE.TorusGeometry(1, boldAdjust * 0.018, 8, 64, Math.PI / 2);
-		let pickGeometry = new THREE.TorusGeometry(1.4, boldAdjust * 0.04, 6, 4, Math.PI / 2);
+		let pickGeometry = new THREE.TorusGeometry(1.4, boldAdjust * 0.06, 6, 4, Math.PI / 2);
 
 		for(let handleName of Object.keys(this.rotationHandles)){
 			let handle = this.handles[handleName];
@@ -771,7 +771,7 @@ export class TransformationTool extends THREE.EventDispatcher{
                 drag.intersectionStart = drag.location;
                 drag.worldPositionStart = posWorld
                   
-                console.log(handle.name)
+                 
                 drag.objectQua = this.selection[0].quaternion.clone()//不考虑父级
                 drag.objectQuaInv = drag.objectQua.clone().invert()
                 this.dragging = true

+ 1 - 8
src/utils/VolumeNew.js

@@ -209,14 +209,7 @@ export class BoxVolume extends Volume{
 		this.boundingBox = this.box.geometry.boundingBox;
 		this.boundingSphere = this.boundingBox.getBoundingSphere(new THREE.Sphere());
 
-		/* if (this._clip) {
-			this.box.visible = false;
-			//this.label.visible = false;
-		} else {
-			this.box.visible = true;
-			//this.label.visible = this.showVolumeLabel;
-		} */
-        
+		 
         viewer.updateVisible(this.box, 'selected', (this.selected || this.hovered) && this.showBox) 
         
         this.box.material.opacity = this.selected ? boxOpacity.selected : boxOpacity.hovered