xzw 2 anni fa
parent
commit
e7d29bbeeb
1 ha cambiato i file con 642 aggiunte e 0 eliminazioni
  1. 642 0
      src/mergeStartTest.js

+ 642 - 0
src/mergeStartTest.js

@@ -0,0 +1,642 @@
+import * as THREE from "../libs/three.js/build/three.module.js";
+import {settings, config} from './settings.js' 
+import math from './utils/math.js' 
+import browser from './utils/browser.js' 
+import './extensions/three.shim.js' 
+import cameraLight from './utils/cameraLight.js' 
+
+import {Utils} from "./utils.js"
+
+
+//多元融合模块
+
+
+var start = function(dom, mapDom, number, fileServer, webSite){ //t-Zvd3w0m
+    //设置:
+    Potree.settings.editType = 'merge'
+    Potree.settings.sidebar = 'sidebar2.html'
+    Potree.settings.intersectOnObjs = true
+    Potree.settings.boundAddObjs = true
+    Potree.settings.showCompass = true
+    
+    
+    Potree.settings.number = number || 't-o5YMR13'// 't-iksBApb'// 写在viewer前 
+    Potree.fileServer = fileServer 
+    webSite && (Potree.settings.webSite = webSite)
+    
+    
+    let viewer = new Potree.Viewer(dom , mapDom);
+    
+    let Alignment = viewer.modules.Alignment
+     
+	viewer.setEDLEnabled(false);
+    viewer.setFOV(config.view.fov); 
+    viewer.loadSettingsFromURL(); 
+    
+    {
+        
+        
+        
+        viewer.mainViewport.view.position.set(100,100,200)
+        viewer.mainViewport.view.lookAt(0,0,0)
+        
+        viewer.updateModelBound()//init
+        //this.bound = new THREE.Box3(new THREE.Vector3(-1,-1,-1),new THREE.Vector3(1,1,1))
+        
+        viewer.transformationTool.setModeEnable('scale',false)
+        viewer.ssaaRenderPass.sampleLevel = 0 //奇怪好像没啥锯齿?  sampleLevel为1 的话,ground就不会
+    }
+    
+     
+    
+    
+    if(!Potree.settings.isOfficial){ 
+        viewer.loadGUI(() => {
+            viewer.setLanguage('en');
+            //$("#menu_appearance").next().show();
+            //$("#menu_tools").next().show();
+            //$("#menu_scene").next().hide();
+            $("#mergeModel").show();
+            viewer.toggleSidebar();
+        });
+        Potree.settings.sizeFitToLevel = true//当type为衰减模式时自动根据level调节大小。每长一级,大小就除以2
+    }
+
+    Potree.loadDatasetsCallback = function(data, ifReload){ 
+        if(!data || data.length == 0)return console.error('getDataSet加载的数据为空')
+           
+        Potree.datasetData = data
+        viewer.transform = null
+        var datasetLength = data.length 
+        var pointcloudLoaded = 0
+        var panosLoaded = 0
+        var pointcloudLoadDone = function(){//点云cloud.js加载完毕后 
+            viewer.updateModelBound()
+            let {boundSize, center} = viewer.bound
+           
+            Potree.Log(`中心点: ${math.toPrecision(center.toArray(),2)}, boundSize: ${math.toPrecision(boundSize.toArray(),2)} ` , null, 12)
+            
+            if(!Potree.settings.isOfficial){
+                Potree.loadMapEntity('all') //加载floorplan 
+            }
+            
+            
+            if(!ifReload){    
+                /* viewer.scene.view.setView({ 
+                    position: center.clone().add(new THREE.Vector3(10,5,10)), 
+                    target: center
+                }) */
+                 
+                viewer.dispatchEvent({type:'loadPointCloudDone'})
+            
+                if(!Potree.settings.UserPointDensity){
+                    Potree.settings.UserPointDensity = 'high'//'middle' 
+                }
+                 
+                Potree.Log('loadPointCloudDone  点云加载完毕', null, 10)  
+            }    
+            
+        }
+        
+        
+        var panosLoadDone = function(){  
+            viewer.images360.loadDone() 
+            viewer.scene.add360Images(viewer.images360); 
+              
+            {//初始位置 
+                var urlFirstView = false
+                var panoId = browser.urlHasValue('pano',true);
+                if(panoId !== ''){
+                    var pos
+                    var pano = viewer.images360.panos.find(e=>e.id==panoId);
+                    if(pano){
+                        viewer.images360.focusPano({
+                            pano,
+                            duration:0, 
+                            callback:()=>{/* Potree.settings.displayMode = 'showPanos' */}
+                        }) 
+                          
+                    }
+                }else{//考虑到多数据集距离很远,或者像隧道那种场景,要使视野范围内一定能看到点云,最好初始点设置在漫游点上
+                    
+                    let {boundSize, center} = viewer.bound 
+                    //let pano = viewer.images360.findNearestPano(center) 
+                    
+                } 
+            }
+             
+            
+            console.log('allLoaded')
+            viewer.dispatchEvent('allLoaded')
+        }
+        
+        var transformPointcloud = (pointcloud, dataset)=>{
+            var locationLonLat = dataset.location.slice(0,2)
+            //当只有一个dataset时,无论如何transform 点云和漫游点都能对应上。
+            var location = viewer.transform.lonlatToLocal.forward(locationLonLat)  //transform.inverse()
+            //初始化位置 
+            
+            viewer.sidebar && viewer.sidebar.addAlignmentButton(pointcloud)  
+            Alignment.rotate(pointcloud, null, dataset.orientation)   
+            Alignment.translate(pointcloud, new THREE.Vector3(location[0], location[1], dataset.location[2])) 
+            
+            pointcloud.updateMatrixWorld() 
+            Potree.Log(`点云${pointcloud.dataset_id}旋转值:${pointcloud.orientationUser}, 位置${math.toPrecision(pointcloud.translateUser.toArray(),3)}, 经纬度 ${locationLonLat}, spacing ${pointcloud.material.spacing}`, null, 17 )
+             
+        }
+        
+        if(!Potree.settings.originDatasetId)Potree.settings.originDatasetId = data[0].id
+        var originDataset =  data.find(e=>e.id == Potree.settings.originDatasetId)  
+        
+        {//拿初始数据集作为基准。它的位置是000
+            var locationLonLat = originDataset.location.slice(0,2)
+            proj4.defs("NAVVIS:TMERC", "+proj=tmerc +ellps=WGS84 +lon_0=" + locationLonLat[0].toPrecision(15) + " +lat_0=" + locationLonLat[1].toPrecision(15));
+            proj4.defs("WGS84", "+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs");
+             
+            let transform1 = proj4("WGS84", "NAVVIS:TMERC"); //这个ok  TMERC是展开的平面投影
+            let transform2 = proj4("+proj=tmerc +lat_0=0 +lon_0=123 +k=1 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m +no_defs;");
+            
+            
+            viewer.transform = {
+                lonlatToLocal : transform1,
+                lonlatTo4550 : transform2       // 转大地坐标EPSG:4550  
+            } 
+            
+            viewer.mapViewer && viewer.mapViewer.mapLayer.maps[0].updateProjection()
+            
+        }
+         
+        
+        data.forEach((dataset,index)=>{  
+            if(!ifReload){
+                var datasetCode = dataset.sceneCode || dataset.name //对应4dkk的场景码
+                var cloudPath = `${Potree.settings.urls.prefix}/${Potree.settings.webSite}/${datasetCode}/data/${datasetCode}/webcloud/cloud.js` 
+                var timeStamp = dataset.createTime ? dataset.createTime.replace(/[^0-9]/ig,'') : '';  //每重算一次后缀随createTime更新一次 
+                //console.warn(dataset.name, 'timeStamp', timeStamp)
+                Potree.loadPointCloud(cloudPath, dataset.name ,datasetCode, timeStamp, e => {
+                    let scene = viewer.scene;
+                    let pointcloud = e.pointcloud; 
+                    let config = Potree.config.material
+                    let material = pointcloud.material; 
+                    
+                    material.minSize =  config.minSize
+                    material.maxSize =  config.maxSize   
+                    material.pointSizeType = config.pointSizeType //Potree.PointSizeType[config.pointSizeType]//Potree.PointSizeType.ADAPTIVE;//FIXED
+                    pointcloud.changePointSize(config.realPointSize)  //material.size =  config.pointSize;
+                    pointcloud.changePointOpacity(1)
+                    material.shape = Potree.PointShape.SQUARE; 
+                    pointcloud.color = pointcloud.material.color = dataset.color  
+                    pointcloud.dataset_id = dataset.id;//供漫游点找到属于的dataset点云
+                    pointcloud.timeStamp = timeStamp 
+                    transformPointcloud(pointcloud,dataset)
+                    scene.addPointCloud(pointcloud);
+                    pointcloudLoaded ++;
+                    if(pointcloudLoaded == datasetLength)pointcloudLoadDone()
+                        
+                    Potree.loadPanos(dataset.id, (data) => { 
+                        //console.log('loadPanos',dataset.sceneCode, dataset.id, data)
+                        viewer.images360.addPanoData(data, dataset.id )
+                        panosLoaded ++; 
+                        if(panosLoaded == datasetLength){
+                            panosLoadDone() 
+                        } 
+                    })
+                })
+            }else{
+                let pointcloud = viewer.scene.pointclouds.find(p => p.dataset_id == dataset.id)
+                if(!pointcloud){
+                    Potree.Log('数据集id变了,自动使用第一个','#500')
+                    pointcloud = viewer.scene.pointclouds[0]
+                }
+                //先归零 
+                Alignment.translate(pointcloud,  pointcloud.translateUser.clone().negate())
+                Alignment.rotate(pointcloud, null,  - pointcloud.orientationUser)
+                
+                transformPointcloud(pointcloud, dataset)
+                 
+            } 
+                
+        }) 
+        
+    } 
+    
+    let setMatrix = (pointcloud)=>{//为了漫游点变换,要算一下 类似setMatrix
+        pointcloud.updateMatrixWorld()       
+        /* pointcloud.transformMatrix = new THREE.Matrix4().multiplyMatrices(pointcloud.matrix, pointcloud.pos1MatrixInvert)//还原一点位移
+        pointcloud.transformInvMatrix.copy(pointcloud.transformMatrix).invert()
+        
+        pointcloud.rotateMatrix = new THREE.Matrix4().makeRotationFromEuler(pointcloud.rotation);
+        pointcloud.rotateInvMatrix.copy(pointcloud.rotateMatrix).invert()
+        pointcloud.panos.forEach(e=>e.transformByPointcloud())   */
+        pointcloud.updateBound()
+        pointcloud.getPanosBound()  
+        viewer.updateModelBound()
+    } 
+
+    let moveModel = (e)=>{//根据鼠标移动的位置改变位置
+          
+        let camera = viewer.mainViewport.camera
+        var origin = new THREE.Vector3(e.pointer.x, e.pointer.y, -1).unproject(camera),
+        end = new THREE.Vector3(e.pointer.x, e.pointer.y, 1).unproject(camera)
+        var dir = end.sub(origin)
+        let planeZ = 0;
+        let r = (planeZ - origin.z)/dir.z
+        let x = r * dir.x + origin.x
+        let y = r * dir.y + origin.y
+        
+        
+        
+        /* if(modelType == 'laser'){ 
+            // modelEditing.translateUser.copy(pos)
+            //Alignment.setMatrix(modelEditing)   
+            let pos = new THREE.Vector3(x,y,  planeZ  )
+        
+            modelEditing.position.copy(modelEditing.initialPosition).add(pos) 
+            
+        }else{ 
+            let pos = new THREE.Vector3(x,y, modelEditing.position.z )
+                
+            modelEditing.position.copy(pos)
+             
+        } */
+        
+        MergeEditor.moveBoundCenterTo(modelEditing,new THREE.Vector3(x,y, modelEditing.boundCenter.z))  //使模型中心的xy在鼠标所在位置
+        
+        
+        modelEditing.dispatchEvent("position_changed")
+         
+    }
+    let cancelMove = ()=>{ 
+        modelEditing = null
+        viewer.removeEventListener('global_mousemove', moveModel); 
+        viewer.removeEventListener('global_click', confirmPos); 
+    }
+    let confirmPos = ()=>{ 
+        focusOnSelect(modelEditing)
+        cancelMove()  
+        return {stopContinue:true}
+    }
+    
+    
+    let focusOnSelect = (object, duration = 400)=>{ 
+         
+        let boundingBox = object.boundingBox.clone().applyMatrix4(object.matrixWorld)
+        let center = boundingBox.getCenter(new THREE.Vector3)
+        let size = boundingBox.getSize(new THREE.Vector3) 
+        let maxSize = size.length() //对角线长度
+        
+        if(object.isPointcloud){
+            maxSize /= 2
+        }
+        
+        let hfov = cameraLight.getHFOVForCamera(viewer.mainViewport.camera,true)
+        let minRadius = maxSize  / Math.tan(hfov/2)
+        //viewer.mainViewport.view.lookAt(center)
+        viewer.mainViewport.view.setView({  
+            position: center.clone().sub(viewer.mainViewport.view.direction.clone().multiplyScalar(minRadius)),
+            target: center,
+            duration 
+        })  //setView can cancel bump
+         
+    }
+    viewer.setControls(viewer.orbitControls) 
+    let modelType,  modelEditing, MergeEditor = viewer.modules.MergeEditor
+    Potree.addModel = function(name, done){ 
+        
+        let isFirstLoad = true
+        cancelMove()
+        modelType = name
+        
+        let loadDone = (model)=>{ 
+            if(isFirstLoad){
+                modelEditing = model;
+                MergeEditor.setModelBtmHeight(model, 0) //默认离地高度为0
+                viewer.addEventListener('global_mousemove', moveModel); 
+                viewer.addEventListener('global_click', confirmPos, 3);
+            }else{
+                modelEditing = null
+            }
+            {//transform
+                let updateBound = ()=>{ 
+                    model.updateMatrixWorld()
+                    viewer.updateModelBound() 
+                }  
+                let maintainBtmZAndCenter = ()=>{
+                    MergeEditor.maintainBoundXY(model)
+                    MergeEditor.setModelBtmHeight(model) 
+                    updateBound()
+                    model.dispatchEvent('transformChanged') 
+                }
+                model.addEventListener('position_changed', ()=>{
+                    updateBound()
+                    MergeEditor.getBoundCenter(model);//更新boundcenter
+                    MergeEditor.computeBtmHeight(model)
+                    model.dispatchEvent('transformChanged') 
+                }) 
+                model.addEventListener("rotation_changed", maintainBtmZAndCenter )
+                model.addEventListener("scale_changed", maintainBtmZAndCenter )
+                
+            
+            }
+            model.updateMatrixWorld()
+            viewer.updateModelBound()
+            
+            MergeEditor.getBoundCenter(model) //初始化
+            
+            
+            
+            model.addEventListener('changeSelect',(e)=>{
+                 e.selected ? MergeEditor.transformControls.attach(model) : MergeEditor.transformControls.detach()
+                //viewer.transformObject(e.selected ? model : null);
+            }) 
+
+            
+            
+            
+            
+            done(model)
+        }
+        
+        
+        
+        if(name == 'laser'){
+            Potree.loadDatasets(Potree.loadDatasetsCallback) 
+            viewer.addEventListener('allLoaded',()=>{
+                let pointcloud = modelEditing = viewer.scene.pointclouds[0]; 
+                pointcloud.matrixAutoUpdate  = true
+                pointcloud.initialPosition = pointcloud.position.clone()
+                
+                 
+                
+                /* pointcloud.addEventListener('select',(e)=>{
+                    if(Potree.settings.displayMode == 'showPanos')return
+                    console.log('select',e) 
+                    //viewer.setControls(viewer.orbitControls) 
+                    focusOnSelect(pointcloud) 
+                    
+                    viewer.outlinePass.selectedObjects = [pointcloud]
+                    return {stopContinue:true}
+                },1)
+                pointcloud.addEventListener('deselect',(e)=>{
+                    console.log('deselect',e) 
+                    //viewer.setControls(viewer.fpControls)  
+                    viewer.outlinePass.selectedObjects = []
+                }) */
+                loadDone(pointcloud)
+            })
+        }else{
+            
+            let callback = (object)=>{
+                //focusOnSelect(object, 1000) 
+                object.traverse(e=>e.material && (e.material.transparent = true))
+                object.isModel = true
+                object.dataset_id = Date.now() //暂时
+                /* object.addEventListener('select',(e)=>{
+                    if(Potree.settings.displayMode == 'showPanos')return
+                    console.log('select',e) 
+                    viewer.setControls(viewer.orbitControls) 
+                    focusOnSelect(object) 
+                    
+                    viewer.outlinePass.selectedObjects = [object]
+                    return {stopContinue:true}
+                },1)
+                object.addEventListener('deselect',(e)=>{
+                    console.log('deselect',e) 
+                    viewer.setControls(viewer.fpControls)  
+                    viewer.outlinePass.selectedObjects = []
+                }) */
+                
+                /* object.addEventListener('click',(e)=>{
+                    //只是为了能得到hoverElement识别才加这个侦听
+                }) */
+                
+                
+                
+                $('#log').text('')  
+
+                  
+                loadDone(object)
+                
+            }
+            let onprogress = (num)=>{
+                $('#log').text("已加载 " + Math.round(num) +" %")
+            }
+            
+            
+            if(name == '4dkk'){ 
+                let num = 't-yAWONOn'
+                var path = `${Potree.scriptPath}/data/4dkk/${num}/` 
+                
+                viewer.loadModel({
+                    name, 
+                    objurl: path+'mesh.obj',    //0.6s
+                    mtlurl: path+'mesh.mtl',
+                    unlit:true,
+                    transform :{ 
+                        rotation : [0,  0,   0],
+                        position : [0,0,0]  
+                    } 
+                },callback,onprogress)
+            }else if(name == 'obj'){
+                /* var path = `${Potree.resourcePath}/models/13/`       
+                viewer.loadModel({
+                    name, 
+                    objurl: path+'w13.OBJ',
+                    mtlurl: path+'w13.mtl',  
+                    transform : { 
+                        rotation : [Math.PI/2,  0,   0],
+                        position : [0,0,0]  
+                    }  
+                },callback,onprogress)  */  
+                    
+                var path = `${Potree.resourcePath}/models/obj/28M/`
+                viewer.loadModel({
+                    name, 
+                    objurl: path+'GW1H.obj',  //解析时间4.392s
+                    mtlurl: path+'GW1H.mtl',    
+                    transform : { 
+                        rotation : [0,  0,   0],
+                        position : [0,0,0]  
+                    }  
+                },callback,onprogress)   
+                
+                /* var path = `${Potree.resourcePath}/models/obj/75M/`
+                viewer.loadModel({
+                    name, 
+                    objurl: path+'Tile_+070_+051.obj',  //解析时间4.945s
+                    mtlurl: path+'Tile_+070_+051.mtl',    
+                    transform : { 
+                        rotation : [0,  0,   0],
+                        position : [0,0,0]  
+                    }  
+                },callback,onprogress) */
+                
+                 
+                
+                
+                
+                /* var path = `${Potree.resourcePath}/models/obj/496M/`
+                viewer.loadModel({
+                    name, 
+                    objurl: path+'Model.obj',  //解析时间25.629 s  期间弹出崩溃提示。很卡 
+                    mtlurl: path+'Model.mtl',     
+                    transform : { 
+                        rotation : [0,  0,   0],
+                        position : [0,0,0]  
+                    }  
+                },callback,onprogress) */
+                
+            }else if(name == 'glb'){
+                
+                let angle = 0
+                let fileName = '87b3a367bc3e4273832cb4fa398782e5.glb'    
+                
+                
+                /* let angle = Math.PI/2
+                let fileName = 'coffeemat.glb',  //0.3s */
+                 
+                  
+                /* let angle =  Math.PI/2
+                let fileName = 'ModernJPHouseSofa44216499.glb' // 21M 
+                   */
+                
+                 
+                /* let angle = 0
+                let fileName = 'cloud_glb_47_loadErrored.glb' //176M  */
+                  
+               
+                
+                var path = `${Potree.resourcePath}/models/glb/` 
+                viewer.loadModel({ 
+                    name, 
+                    glburl: path+fileName,
+                    transform : { 
+                        rotation : [angle,  0,   0],
+                        position : [0,0,0]  
+                    } 
+                },callback,onprogress)
+                  
+                
+            }else if(name == '3dTiles'){
+                
+                
+            }
+             
+        }  
+    }
+    
+    let getModelByName = (name)=>{
+        if(name == 'laser'){
+            return viewer.scene.pointclouds[0]
+        }else{
+            return viewer.objs.children.find(e=>e.name == name)
+        }    
+    }
+    
+    Potree.removeModel = function(name){
+        let model = getModelByName(name)
+        if(name == 'laser'){ 
+            viewer.scene.removePointCloud(model);
+            viewer.updateModelBound() 
+        }else{  
+            viewer.removeObj(model) 
+        }
+        cancelMove()
+    }
+     
+    
+    /* Potree.selectModel = function(name){
+        let model = getModelByName(name) 
+        model && viewer.transformObject(model)
+    } */
+    
+    //Potree.loadDatasets(Potree.loadDatasetsCallback) 
+     
+     
+   
+     
+    viewer.inputHandler.addEventListener('keydown', (e)=>{
+        if(e.event.key == "e" ){ 
+           MergeEditor.transformControls.mode = 'rotate'
+        }else if(e.event.key == "w"){
+            MergeEditor.transformControls.mode = 'translate'
+        }
+    })
+     
+ 
+
+    window.THREE = THREE
+    window.buttonFunction = function(){ 
+        viewer.scene.pointclouds.forEach(e=>e.predictNodeMaxLevel())
+              
+    }
+}
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+/* var changeLog = ()=>{ //如果移动端加了test反而出不来bug的话,用这个
+        
+    
+        var textarea = document.createElement('textarea');
+          textarea.id = "consoleLog";
+          
+          textarea.style.width = '160px';
+          textarea.style.height =  '200px'
+          textarea.style.position = 'fixed'
+          textarea.style.right = 0
+          textarea.style.bottom = '0'
+          textarea.style['z-index'] = 9999;
+          textarea.style.color = 'black';
+          textarea.style.opacity = 0.9;
+          textarea.style['font-size'] = '12px';
+          textarea.style['backgroundColor'] = '#ffffff'
+         
+          
+
+          document.getElementsByTagName("body")[0].appendChild(textarea);
+          var list = ["log", "error", "warn", "debug", "info", "time", "timeEnd"]
+          var exchange = function (o) {
+            console["old" + o] = console[o];
+            console[o] = function () {
+              var args =   Array.from(arguments)
+              console["old" + o].apply(this, arguments)
+              var t = document.getElementById("consoleLog").innerHTML;
+              
+              var str = ''
+              args.forEach(a=>{
+                  str += a + ' '
+              })
+              document.getElementById("consoleLog").innerHTML = str + "\n\n" + t;
+            }
+          }
+
+          for (var i = 0; i < list.length; i++) {
+            exchange(list[i])
+          } 
+   
+    
+    
+}
+ 
+changeLog() */
+ //可以直接用edlShader来渲染obj的outline,但不能渲染被遮挡的部分 
+ 
+ 
+ 
+export {start}
+
+
+