Bläddra i källkod

新版融合 可以漫游

xzw 1 år sedan
förälder
incheckning
2612da20f7

+ 1 - 1
gulpfile.js

@@ -97,7 +97,7 @@ gulp.task('webserver', gulp.series(async function() {
 	server = connect.server({
 		port: 1234,
         host:'0.0.0.0',
-		https: false,
+		https: true,
         middleware: function(connect, opt) {
           return [
             // 首先,使用addResponseHeaders中间件来设置响应头

+ 5 - 0
libs/gaussian/gaussian-splats-3d.module.js

@@ -14,6 +14,11 @@ let Ray$1 = THREE.Ray, Plane = THREE.Plane, MathUtils = THREE.MathUtils,  EventD
  
     //加 
     {
+        
+        
+        const _tables = /*@__PURE__*/ _generateTables();
+
+        
         function _generateTables() {
 
             // float32 to float16 helpers

+ 5 - 11
libs/three.js/3dtiles/three-loader-3dtiles.esm.js

@@ -40,18 +40,12 @@ let maxDepth = 100
 
 function getGpuMemoryUsage(win = window){//总的
     let c = 0
-    viewer.objs.children.filter(e=>{
-        if(e.fileType == '3dTiles'){ 
-           e.traverse(child=>{
-                if(child.runtime){
-                    let tileset3D = child.runtime.getTileset()
-                    c += tileset3D.gpuMemoryUsageInBytes
-                    return {stopContinue:true} 
-                }
-            }) 
-        }
-    })
     
+    viewer.setAllTilesets(model=>{
+        let tileset3D = model.runtime.getTileset()
+        c += tileset3D.gpuMemoryUsageInBytes
+    })
+     
     if(win.parent != win){//还有父级页面。 暂时只有子级需要考虑父级,假设父级在前台时子级已经销毁
         c += getGpuMemoryUsage(win.parent)
     } 

+ 6 - 5
libs/three.js/loaders/GLTFLoader.js

@@ -3340,11 +3340,12 @@ class GLTFParser {
                     loader.load(url, onLoad, undefined, reject );
                 }else{
                     //为了防止chrome出现报错  The source image could not be decoded. 导致reject,重新写贴图加载方式: xzw   //但不知道为何有的场景(如4dkk的)不成功
-                    parser.textureLoader.load(sourceURI, (tex)=>{ 
-                        THREE.LinearMipmapLinearFilter //原本:NearestMipMapNearestFilter 闪烁 有一个block文件离远了有裂缝,只能使用LinearFilter,但是这样似乎更卡,且锯齿
-                        /* tex.minFilter = THREE.LinearFilter
-                        tex.generateMipmaps = false */ 
-                         
+                    parser.textureLoader.load(sourceURI, (tex)=>{  
+                        //原本:NearestMipMapNearestFilter 闪烁 有一个block文件离远了有裂缝,只能使用LinearFilter,但是这样似乎更卡,且锯齿
+                        /* {//处理裂缝
+                            tex.minFilter = THREE.LinearFilter
+                            tex.generateMipmaps = false   
+                        } */
                         //console.log(tex.image.width, tex.image.height)
                            
                         resolve(tex) 

+ 69 - 1
src/Potree.js

@@ -281,11 +281,13 @@ export async function loadMapEntity(datasetId, force){
     
 }
  
-export async function loadPanos(datasetId, callback){
+export async function loadPanos(datasetId, callback, number){
     var path 
     //let query = `?datasetId=${datasetId}`                  //`?lat=${center.lat}&lon=${center.lon}&radius=200000`
     if(Potree.fileServer){
         path = `/laser/filter/${Potree.settings.number}/query` 
+    }else if(Potree.settings.mergeType2){ //每个场景只加载初始数据集
+        path = `${Potree.settings.urls.prefix}/laser/filter/${number}/query` 
     }else{
         //path = `${Potree.settings.urls.prefix2}/indoor/${Potree.settings.number}/api/images/filter` + query
         //path = `${Potree.scriptPath}/data/${Potree.settings.number}/panos-${datasetId}.json`
@@ -310,6 +312,69 @@ export async function loadPanosInfo(callback){
     
 }
 
+export function load4dkkPanos(sceneCode, model, done){ //加载四维看看的漫游点并转换
+    model.is4dkkModel = true
+    model.panos = []
+    //模拟点云,需要rotX(90)+平移一段才能和四维看看的bound一样
+    let rot1M = new THREE.Matrix4().makeRotationX(Math.PI/2);
+    let pos1 = new THREE.Vector3
+    pos1.fromArray(model.runtime.getTileset().tileset.root.boundingVolume.box.slice(0,3))//必须要平移一段才能重合 
+    pos1.copy(Potree.math.convertVector.ZupToYup(pos1))
+    let pos1M = new THREE.Matrix4().setPosition(pos1)
+    model.posRot1MatrixInvert = new THREE.Matrix4().multiplyMatrices(pos1M, rot1M ).invert();
+    model.rot1MatrixInvert = rot1M.clone().invert();
+    
+    model.transformMatrix = new THREE.Matrix4
+    model.rotateMatrix = new THREE.Matrix4
+    model.datasetData = {
+        sceneVersion : 'V4'
+    }
+    model.sceneCode = sceneCode
+    model.bound = new THREE.Box3
+    
+    let path = `https://4dkk.4dage.com/scene_view_data/${sceneCode}/images/vision.txt`
+    loadFile(path,{},(data)=>{
+         
+        let panoData = data.sweepLocations.map(e=>{
+            let qua = e.pose.rotation
+            return {
+                file_id : e.uuid,
+                dataset_location : new THREE.Vector3().copy(e.pose.translation).toArray(),
+                dataset_floor_location : new THREE.Vector3().copy(e.puck).toArray(),
+                dataset_orientation: [qua.w, qua.x, qua.y, qua.z],
+                
+            }
+        })
+        viewer.images360.addPanoData(panoData, model)
+        viewer.images360.loadDone()   
+        viewer.scene.add360Images(viewer.images360);
+        
+        {//neighbourMap全部填满,否则之后会被修改
+            data.sweepLocations.forEach(pano1Data=>{ 
+                let pano1 = model.panos.find(e=>e.originID == pano1Data.uuid)
+                model.panos.forEach((pano2, i)=>{
+                    if(pano1 == pano2)return
+                    let v = pano1Data.visibles.includes(i) 
+                    viewer.images360.neighbourMap[pano1.id][pano2.id] = v
+                    viewer.images360.neighbourMap[pano2.id][pano1.id] = v
+                    if(v){
+                        pano1.neighbours.includes(pano2) || pano1.neighbours.push(pano2)
+                        pano2.neighbours.includes(pano1) || pano2.neighbours.push(pano1)
+                    }
+                })
+            }) 
+        }
+        
+        
+        
+        viewer.modules.MergeEditor.modelTransformCallback(model, true) //初始化pano的pose
+        done()
+    })
+    /*  neighbours: e.visibles3 || e.visibles,
+        noBlocks: e.visibles2,
+        seeMarkers: e.visibles, */
+    
+}
 
 
 export async function loadImgVersion( callback){
@@ -327,6 +392,9 @@ export async function loadImgVersion( callback){
 
 
 
+
+
+
 //site_model
 /* {
     "area": 2503.30551910935,

+ 1 - 1
src/custom/materials/FastTranPass.js

@@ -111,7 +111,7 @@ export default class FastTranPass {
     
     stop(){
         this.enabled = false
-        console.log('stop111')
+        //console.log('stop111')
     }
     
     getMaskMaterial(){

+ 40 - 6
src/custom/mergeStartTest.js

@@ -133,7 +133,7 @@ var start = function(dom, mapDom, number, fileServer, webSite){ //t-Zvd3w0m
                 } 
             }
              
-            
+             
             console.log('allLoaded')
             viewer.dispatchEvent('allLoaded')
         }
@@ -195,6 +195,8 @@ var start = function(dom, mapDom, number, fileServer, webSite){ //t-Zvd3w0m
                     let config = Potree.config.material
                     let material = pointcloud.material; 
                     
+                    pointcloud.datasetData = dataset
+                    
                     material.minSize =  config.minSize
                     material.maxSize =  config.maxSize   
                     material.pointSizeType = config.pointSizeType //Potree.PointSizeType[config.pointSizeType]//Potree.PointSizeType.ADAPTIVE;//FIXED
@@ -315,7 +317,7 @@ var start = function(dom, mapDom, number, fileServer, webSite){ //t-Zvd3w0m
         })  //setView can cancel bump
         MergeEditor.selectModel(object,true) 
     }
-    viewer.setControls(viewer.orbitControls) 
+    //viewer.setControls(viewer.orbitControls) 
      
       
              
@@ -391,6 +393,7 @@ var start = function(dom, mapDom, number, fileServer, webSite){ //t-Zvd3w0m
                 model.addEventListener("scale_changed", maintainBtmZAndCenter )
                 model.addEventListener('transformChanged', ()=>{
                     MergeEditor.modelTransformCallback(model)
+                    
                 })
             
             }
@@ -420,8 +423,9 @@ var start = function(dom, mapDom, number, fileServer, webSite){ //t-Zvd3w0m
             viewer.addEventListener('allLoaded',()=>{
                 let pointcloud = modelEditing = viewer.scene.pointclouds[0]; 
                 pointcloud.matrixAutoUpdate  = true
-                pointcloud.initialPosition = pointcloud.position.clone()
-                
+                pointcloud.initialPosition = pointcloud.position.clone() 
+                pointcloud.pos1MatrixInvert = new THREE.Matrix4().setPosition(pointcloud.initialPosition).invert()
+                    
                  
                 
                 /* pointcloud.addEventListener('select',(e)=>{
@@ -559,7 +563,7 @@ var start = function(dom, mapDom, number, fileServer, webSite){ //t-Zvd3w0m
                 
                  
                 let angle = 0
-                let fileName = 'archmodels95_043.glb'//纯色
+                let fileName = 'archmodels95_043.glb'//'block-远看有裂缝.glb'//'archmodels95_043.glb'//纯色
                 
                 //'26k.glb' //176M  
                   
@@ -694,8 +698,38 @@ var start = function(dom, mapDom, number, fileServer, webSite){ //t-Zvd3w0m
                         },onprogress)
                  },onprogress)
                    
+            }else if(name == 'shp'){
+
+                let callback = (object)=>{ 
+                    object.isModel = true  
+                    loadDone(object)
+                } 
+ 
+                
+                viewer.loadModel({  
+                    fileType: 'shp',  
+                    name : 'shp',
+                    url:  Potree.resourcePath+'/models/shape-jiangmen/jiangmen.shp',
+                    
+                },callback,onprogress)
+      
+              
+                //shpModel.position.set(-330000, 900000,10)//尽量移动到原点。原位置在江门那
+                 
+            
+            }else if(name == '3dgs'){ 
+            
+                let callback = (object)=>{ 
+                    object.isModel = true 
+                    
+                    loadDone(object)
+                } 
+                viewer.loadModel({  
+                    fileType: '3dgs',   
+                    url: Potree.resourcePath+'/models/gaussian/bonsai.ksplat', 
+                    
+                },callback,onprogress)
             }
-             
         }  
     }
     

+ 64 - 4
src/custom/modules/mergeModel/MergeEditor.js

@@ -11,16 +11,19 @@ import InfiniteGridHelper from '../../objects/InfiniteGridHelper.js'
 import Compass from "../../objects/tool/Compass.js";
 import {TransformControls} from "../../objects/tool/TransformControls.js";
 import History from "../../utils/History.js"
-
+import {Box3Helper} from "../../../utils/Box3Helper.js";
+ 
  
 const texLoader = new THREE.TextureLoader() 
       texLoader.crossOrigin = "anonymous" 
+
+   
   
 const edgeStrengths = {
     pointcloud: 4,
     glb: 100
 }
-const viewportProps = [{
+const viewportProps = [{ 
     left:0,
     bottom:0,
     width: 0.5,height:1,
@@ -55,6 +58,12 @@ let MergeEditor = {
     
     init(){  
     
+        this.boxHelper = new Box3Helper(new THREE.Box3(new THREE.Vector3(-0.5,-0.5,-0.5), new THREE.Vector3(0.5,0.5,0.5)));
+        viewer.scene.scene.add(this.boxHelper)
+        Potree.Utils.updateVisible(this.boxHelper,'unselect',false)
+        
+        
+        
     
         this.history = new History({ 
             applyData: (data)=>{ 
@@ -501,8 +510,36 @@ let MergeEditor = {
         
     },
     
+    updateBoxHelper(model){
+        let size = new THREE.Vector3
+        model.boundingBox.getSize(size)
+        size.multiply(model.scale)
+        this.boxHelper.scale.copy(size) 
+        
+        let center = new THREE.Vector3 
+        model.boundingBox.getCenter(center) 
+        center.applyMatrix4(model.matrixWorld)
+        //center.add(model.position)     
+        this.boxHelper.position.copy(center)
+         
+        this.boxHelper.quaternion.copy(model.quaternion)  
+    },
+    
+     
     
     showModelOutline(model, state){ 
+        if(Potree.settings.mergeType2){//高斯很卡
+            if(state !== false ){
+                this.updateBoxHelper(model) 
+                Potree.Utils.updateVisible(this.boxHelper,'unselect',true)
+            }else{ 
+                Potree.Utils.updateVisible(this.boxHelper,'unselect',false)
+            }
+            return
+        }
+        
+        
+        
         if(this.fadeOutlineAuto){ 
             if(state === false){
                 viewer.outlinePass.selectedObjects = []
@@ -634,10 +671,10 @@ let MergeEditor = {
         model.boundCenter.copy(center1)
     },
     
-    modelTransformCallback(model){
+    modelTransformCallback(model,force){
         
         model.updateMatrixWorld() 
-        if(model.matrixWorld.equals(model.lastMatrixWorld))return
+        if(!force && model.matrixWorld.equals(model.lastMatrixWorld))return
         viewer.scene.measurements.forEach(measure=>{
             let changed
             measure.points_datasets.forEach((dataset_id,i)=>{
@@ -655,9 +692,32 @@ let MergeEditor = {
             }
         }) 
         
+        //反向求transformMatrix  参考Alignment.js   移动漫游点 
+        if(model.isPointcloud && model.transformMatrix){ 
+            model.transformMatrix.multiplyMatrices(model.matrix, model.pos1MatrixInvert)   
+            model.transformInvMatrix.copy(model.transformMatrix).invert()      
+            model.rotateMatrix = new THREE.Matrix4().makeRotationFromEuler(model.rotation);            
+            model.panos.forEach(e=>e.transformByPointcloud())
+        }else if(model.panos){ 
+            model.rotateMatrix = new THREE.Matrix4().makeRotationFromEuler(model.rotation).multiply(model.rot1MatrixInvert);   
+ 
+            model.transformMatrix.multiplyMatrices(model.matrix, model.posRot1MatrixInvert)   
+            model.panos.forEach(e=>e.transformByPointcloud())
+            model.bound = model.boundingBox.clone().applyMatrix4(model.matrixWorld)
+        } 
+        
+        
+        
+        
+        
         model.lastMatrixWorld = model.matrixWorld.clone()
         viewer.dispatchEvent('content_changed')
         viewer.mapViewer && Potree.settings.showObjectsOnMap && viewer.mapViewer.dispatchEvent('content_changed')
+        
+        
+        //--------
+        this.updateBoxHelper(model)
+        
     },
     
     

+ 33 - 26
src/custom/modules/panos/Images360.js

@@ -155,7 +155,8 @@ export class Images360 extends THREE.EventDispatcher{
             if(e.clickElement ||
                 Potree.settings.unableNavigate || this.flying  || !e.isTouch && e.button != THREE.MOUSE.LEFT || e.drag &&  e.drag.object //拖拽结束时不算
                || Potree.settings.editType == 'pano' && viewer.modules.PanoEditor.activeViewName != 'mainView'
-                ||   Potree.settings.editType == 'merge' && !e.intersectPoint || viewer.inputHandler.hoveredElements[0] && viewer.inputHandler.hoveredElements[0].isModel && e.intersectPoint.distance > viewer.inputHandler.hoveredElements[0].distance
+             //   ||   Potree.settings.editType == 'merge' && !e.intersectPoint || viewer.inputHandler.hoveredElements[0] && viewer.inputHandler.hoveredElements[0].isModel && e.intersectPoint.distance > viewer.inputHandler.hoveredElements[0].distance
+                || Potree.settings.mergeType2 && Potree.settings.displayMode == 'showPointCloud'
             )  return 
              
             if(Potree.settings.editType != 'pano' && Potree.settings.editType != 'merge'){
@@ -444,7 +445,7 @@ export class Images360 extends THREE.EventDispatcher{
                                 })
                             }  
                             this.updateCube(this.currentPano)
-                            
+                            //viewer.setControls(viewer.fpControls)
                         }else{
                             if(camera.limitFar)   camera.far = Potree.settings.cameraFar;//修改far
                             Potree.settings.pointDensity = Potree.settings.UserPointDensity   
@@ -455,6 +456,7 @@ export class Images360 extends THREE.EventDispatcher{
                                     e.material.pointSizeType = Potree.config.material.pointSizeType
                                 }) 
                             }
+                            //Potree.settings.editType == 'merge' && viewer.setControls(viewer.orbitControls)
                         }   
                         camera.updateProjectionMatrix() 
                         
@@ -584,9 +586,9 @@ export class Images360 extends THREE.EventDispatcher{
         
     }
     
-    findNearestPano(pos){
+    findNearestPano(pos, panos=this.panos){
         pos = pos ? new THREE.Vector3().copy(pos) : this.position
-        let result = Common.sortByScore(this.panos,[Images360.filters.isEnabled()],[e=>-e.position.distanceTo(pos)])
+        let result = Common.sortByScore(panos,[Images360.filters.isEnabled()],[e=>-e.position.distanceTo(pos)])
         let pano = result[0] && result[0].item
         return pano
         
@@ -632,7 +634,7 @@ export class Images360 extends THREE.EventDispatcher{
     
  
  
-    isAtPano(precision){//是否在某个漫游点上  
+    isAtPano(precision=1e-6){//是否在某个漫游点上  
         if(precision){
             return this.currentPano && math.closeTo(viewer.scene.view.position, this.currentPano.position, precision)
         }
@@ -923,7 +925,7 @@ export class Images360 extends THREE.EventDispatcher{
                         viewer.scene.pointclouds.forEach(e=>{
                             e.material.stopProjectedPanos()
                         })
-                    }
+                    } 
                     this.lastPano = this.currentPano //记录,调试
                     this.currentPano = pano;
                     
@@ -931,14 +933,12 @@ export class Images360 extends THREE.EventDispatcher{
                     if(Potree.settings.displayMode == 'showPanos'){
                         viewer.scene.pointclouds.forEach(e=>{
                             Potree.Utils.updateVisible(e, 'displayMode',pointcloudVisi) 
-                        })
+                        }) 
                     }
                     done(true);
                    
                     this.updateDepthTex(this.currentPano) //删除dispose的depthTex
-                    
-                    
-                    
+                     
                 }, 
                 cancelFun:()=>{ done(false, true) },
                 Easing:toPano.easeName,
@@ -1401,7 +1401,7 @@ export class Images360 extends THREE.EventDispatcher{
             }
         }else if(!onlyUseTex && !ifNeighbour){//使用点云判断(有深度贴图时不会执行到这)
             
-            let inDirection = ()=>{
+            /* let inDirection = ()=>{
                 let dir = new THREE.Vector3().subVectors(pano1.position,pano0.position).normalize()
                 let dis = pano1.position.distanceTo(pano0.position)
                 let fov = THREE.Math.degToRad(viewer.mainViewport.camera.fov)
@@ -1423,11 +1423,14 @@ export class Images360 extends THREE.EventDispatcher{
                 if(ifNeighbour && !inDirection()){
                     ifNeighbour = undefined //不确定
                 } 
-            }
+
+            } 
+            map0[pano1.id] = map1[pano0.id] = ifNeighbour ? 'byCloud' : ifNeighbour//写简单点
+            */
                 
 
+            map0[pano1.id] = map1[pano0.id] = true  //全部可通行
             
-            map0[pano1.id] = map1[pano0.id] = ifNeighbour ? 'byCloud' : ifNeighbour//写简单点
             
         }
                                                                        
@@ -1744,7 +1747,7 @@ export class Images360 extends THREE.EventDispatcher{
     getTileDirection(){//根据不同dataset的来存储
         var vectorForward = viewer.scene.view.direction.clone() 
             
-        var vectorForwards = viewer.scene.pointclouds.map(e=>{
+        var vectorForwards = viewer.scene.pointclouds.concat(viewer.objs.children.filter(e=>e.panos)).map(e=>{
             var inv = new THREE.Matrix4().copy(e.rotateMatrix).invert()//乘上dataset的旋转的反转
             var direction = vectorForward.clone().applyMatrix4(inv)
             return {
@@ -2468,16 +2471,17 @@ export class Images360 extends THREE.EventDispatcher{
     //缩小后继续显示cube呢还是不显示?  不显示的话,就要把cube上的复制到renderTarget上……会不会又崩溃,or没加载的显示???
     
     
-    addPanoData(data, datasetId ){//加载漫游点
+    addPanoData(data, pointcloud ){//加载漫游点
         //data[0].file_id = '00019'
          
         if(data.data) data = data.data 
-        if(data.length == 0)console.error(datasetId + ' 没有漫游点') 
+        if(data.length == 0)console.error(pointcloud.dataset_id + ' 没有漫游点') 
         //data = data.sort(function(a,b){return a.id-b.id})
         
         data.forEach((info)=>{  
             //if(Potree.fileServer){
                 info.id = this.panos.length             //把info的id的一长串数字改简单点
+                info.pointcloud = pointcloud
             //} 
             let pano = new Panorama( info, this   );
              
@@ -2486,6 +2490,11 @@ export class Images360 extends THREE.EventDispatcher{
             })
             
             this.panos.push(pano);
+            
+            this.neighbourMap[info.id] = {}
+            pano.label && Potree.Utils.setObjectLayers(pano.label, 'bothMapAndScene') 
+            pano.label2 && Potree.Utils.setObjectLayers(pano.label2, 'bothMapAndScene') 
+            
             if(Potree.settings.editType == 'pano'){
                 Potree.settings.datasetsPanos[datasetId].panos.push(pano);
             }
@@ -2495,15 +2504,10 @@ export class Images360 extends THREE.EventDispatcher{
     
     loadDone(){
         Potree.Utils.setObjectLayers(this.node, 'sceneObjects')
-        //this.updateCube(/* viewer.bound */)
-        
-        this.panos.forEach(e=>{
-            this.neighbourMap[e.id] = {}
-            e.label && Potree.Utils.setObjectLayers(e.label, 'bothMapAndScene') 
-            e.label2 && Potree.Utils.setObjectLayers(e.label2, 'bothMapAndScene') 
-        }) 
+   
+          
         
-        this.tileDownloader.setPanoData(this.panos, [] /* , Potree.settings.number */);
+        this.tileDownloader.setPanoData(this.panos, [] );
 
         {        
             let minSize = new THREE.Vector3(1,1,1)
@@ -2815,13 +2819,16 @@ Images360.prototype.updateCube = (function(){//增加细分的版本,且垂直
     let minBeta = Math.atan(minTanBeta)
     const maxSinAlpha = Math.cos(minBeta) // 注:beta = Math/2 - alpha
     const skyHeight = 50
+     
     return function(pano0, pano1){
     
         if(Potree.settings.displayMode != 'showPanos' || pano0 == pano1
-            ||  this.cubePanos.includes(pano0) && this.cubePanos.includes(pano1) 
+            || this.cubePanos.some(e=>e.pano == pano0 && e.matrix.equals(pano0.pointcloud.matrix))
+            && (!pano1 || this.cubePanos.some(e=>e.pano == pano1 && e.matrix.equals(pano1.pointcloud.matrix)))
         ) return 
         
-        this.cubePanos = [pano0, pano1]
+        this.cubePanos = [{pano:pano0,  matrix:pano0.pointcloud.matrix.clone()},
+                        {pano:pano1,  matrix:pano1 && pano1.pointcloud.matrix.clone()}]
         
         viewer.addTimeMark('updateCube','start')
          

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

@@ -148,7 +148,7 @@ class Panorama extends THREE.EventDispatcher{
             
             this.originID = parseInt(o.file_id)//"file_id":"00022"对应是原本的4dkk的id --来自vision.txt
              
-            this.pointcloud = viewer.scene.pointclouds.find(e=>e.dataset_id == o.dataset_id) || viewer.scene.pointclouds[0]
+            this.pointcloud = o.pointcloud //viewer.scene.pointclouds.find(e=>e.dataset_id == o.dataset_id) || viewer.scene.pointclouds[0]
             this.pointcloud.panos.push(this)
             
             //this.sid = this.pointcloud.sceneCode + '|' + this.originID  //不会更改的标记

+ 1 - 1
src/custom/settings.js

@@ -476,7 +476,7 @@ let settings = {//设置   可修改
     areaAtNotPlane: false,
     
     
-    fastTran: isTest
+    //fastTran: isTest
 }
  
 

+ 43 - 42
src/custom/start.js

@@ -561,7 +561,7 @@ export function start(dom, mapDom, number ){ //t-Zvd3w0m
                 
                     Potree.loadPanos(dataset.id, (data) => { 
                         //console.log('loadPanos',dataset.sceneCode, dataset.id, data)
-                        viewer.images360.addPanoData(data, dataset.id )
+                        viewer.images360.addPanoData(data, pointcloud)
                         panosLoaded ++; 
                         if(panosLoaded == datasetLength){
                             
@@ -839,7 +839,7 @@ export function panoEditStart(dom, number, fileServer){
                  
                 if(pointcloudLoaded == panoCount ){
                     datasetLoaded ++
-                    viewer.images360.addPanoData(panoData ,  datasetId )
+                    viewer.images360.addPanoData(panoData ,  pointcloud )
                     if(datasetLoaded == datasetsCount){
                         pointcloudLoadDone()
                     }
@@ -895,16 +895,22 @@ export function mergeEditStart(dom, mapDom){
     
     Potree.settings.sizeFitToLevel = true//当type为衰减模式时自动根据level调节大小。每长一级,大小就除以2
     Potree.loadPointCloudScene = function(url, type, id, title, done, onError){//对应4dkk的场景码
-          
+        let dataset 
         let loadCloud = ({cloudPath, sceneName, sceneCode, timeStamp, color } )=>{
             
             Potree.loadPointCloud(cloudPath, sceneName , sceneCode, timeStamp, e => {
-                 
+                
+
+                
                 let scene = viewer.scene;
                 let pointcloud = e.pointcloud; 
                 let config = Potree.config.material
                 let material = pointcloud.material; 
                 
+                pointcloud.datasetData = dataset
+                pointcloud.hasDepthTex = dataset && Potree.settings.useDepthTex && !!dataset.has_depth    
+
+                
                 material.minSize =  config.minSize
                 material.maxSize =  config.maxSize   
                 material.pointSizeType = config.pointSizeType //Potree.PointSizeType[config.pointSizeType]//Potree.PointSizeType.ADAPTIVE;//FIXED
@@ -929,14 +935,9 @@ export function mergeEditStart(dom, mapDom){
                     Potree.Log('loadPointCloudDone  点云加载完毕',  {font:[null,10] })    
                 } 
                     
-                /* Potree.loadPanos(dataset.id, (data) => { //暂时不加载panos了,因为没有id 
-                //console.log('loadPanos',dataset.sceneCode, dataset.id, data)
-                viewer.images360.addPanoData(data, dataset.id ) 
-                viewer.images360.loadDone() 
-                viewer.scene.add360Images(viewer.images360);    */   
+               
                 viewer.dispatchEvent('allLoaded')
                  
-                
                 done(pointcloud)
             },onError) 
             
@@ -950,13 +951,13 @@ export function mergeEditStart(dom, mapDom){
                 let timeStamp = originDataset.updateTime ? originDataset.updateTime.replace(/[^0-9]/ig,'') : '';  //每重算一次后缀随updateTime更新一次 
                 //let cloudPath = `${Potree.settings.urls.prefix1}/${Potree.settings.webSite}/${sceneCode}/data/${sceneCode}/webcloud/cloud.js` 
                 let cloudPath = `${Potree.settings.urls.prefix1}/${originDataset.webBin}`  //webBin添加原因:每次裁剪之类的操作会换路径,因为oss文件缓存太严重,更新慢
-                
+                dataset = originDataset
                 loadCloud({cloudPath, sceneName:originDataset.sceneName, sceneCode, timeStamp, color:originDataset.color})
             }, sceneCode, onError)
         
         }else{//las or ply  直接用url
             let name = type + '|' + id + '|' + title
-             
+            //有漫游点吗
             if(url instanceof Array){
                 if(url.length == 1){
                     url = url[0]
@@ -1107,7 +1108,12 @@ export function mergeEditStart(dom, mapDom){
             viewer.updateModelBound()
             
             MergeEditor.getBoundCenter(model) //初始化
-            model.lastMatrixWorld = model.matrixWorld.clone()
+            //model.lastMatrixWorld = model.matrixWorld.clone()
+            model.lastMatrixWorld = new THREE.Matrix4
+            MergeEditor.modelTransformCallback(model)
+            
+            
+            
             
             done(model) // 先发送成功,因为2d界面会随机执行changePosition等初始化,然后这边再将模型移到中心地面上
             
@@ -1138,6 +1144,9 @@ export function mergeEditStart(dom, mapDom){
              
             MergeEditor.modelAdded(model)
             
+            
+            
+            
         }
          
          
@@ -1163,7 +1172,7 @@ export function mergeEditStart(dom, mapDom){
             let info = { 
                 fileType: prop.type, 
                 id: prop.id,
-                //unlit:true,
+                unlit: prop.unlit,
                 url : prop.url,
                 name : prop.title,
                 /* transform : { 
@@ -1210,7 +1219,16 @@ export function mergeEditStart(dom, mapDom){
                 
             },callback,onprogress)
         
-        }else if(prop.type == 'shp'){ 
+        }else if(prop.type == 'shp'){
+
+            let callback = (object)=>{
+                  
+                object.isModel = true  
+                loadDone(object)
+            } 
+
+
+            
             viewer.loadModel({  
                 fileType: 'shp', 
                 id: prop.id,
@@ -1253,37 +1271,20 @@ export function mergeEditStart(dom, mapDom){
  
             Potree.loadPointCloudScene(prop.url, prop.type, prop.modelId, prop.title, (pointcloud)=>{  
                 pointcloud.matrixAutoUpdate = true
-                pointcloud.initialPosition = pointcloud.position.clone()
-                
+                pointcloud.initialPosition = pointcloud.position.clone() 
                 pointcloud.pos1MatrixInvert = new THREE.Matrix4().setPosition(pointcloud.initialPosition).invert()
                 
-                /* let maintainBtmZ = ()=>{
-                    MergeEditor.setModelBtmHeight(pointcloud)
-                    updateMatrix()
-                }
-                let updateMatrix = ()=>{ 
-                    setMatrix(pointcloud) 
-                    pointcloud.dispatchEvent('transformChanged')
+                if(Potree.settings.mergeType2 && pointcloud.datasetData){
+                    Potree.loadPanos(pointcloud.datasetData.id, (data) => { 
+                        viewer.images360.addPanoData(data, pointcloud )
+                        viewer.images360.loadDone() 
+                        viewer.scene.add360Images(viewer.images360); 
+                        loadDone(pointcloud)
+                    },prop.url)
+                }else{
+                    loadDone(pointcloud)
                 }
-                pointcloud.addEventListener('position_changed', updateMatrix )  
-                pointcloud.addEventListener("orientation_changed", maintainBtmZ )
-                pointcloud.addEventListener("scale_changed", maintainBtmZ ) */
                 
-                loadDone(pointcloud)
-                /* pointcloud.addEventListener('select',(e)=>{
-                    if(Potree.settings.displayMode == 'showPanos')return
-                    console.log('select',e) 
-                    //viewer.setControls(viewer.orbitControls) 
-                    MergeEditor.focusOnSelect(pointcloud) 
-                    
-                    viewer.outlinePass.selectedObjects = [pointcloud]
-                    return {stopContinue:true}
-                },{importance:1})
-                pointcloud.addEventListener('deselect',(e)=>{
-                    console.log('deselect',e) 
-                    //viewer.setControls(viewer.fpControls)  
-                    viewer.outlinePass.selectedObjects = []
-                }) */
                 
             }, onError)
         

+ 100 - 82
src/custom/viewer/ViewerNew.js

@@ -1,6 +1,6 @@
  
 
-//import * as GaussianSplats3D from "../../../libs/gaussian/gaussian-splats-3d.module.js";
+import * as GaussianSplats3D from "../../../libs/gaussian/gaussian-splats-3d.module.js";
 
 import {Loader3DTiles} from '../../../libs/three.js/3dtiles/three-loader-3dtiles.esm.js'; 
 import {OBJLoader} from "../../../libs/three.js/loaders/OBJLoader.js";
@@ -15,7 +15,7 @@ import {TagTool} from "../objects/tool/TagTool.js";
 import Compass from "../objects/tool/Compass.js";
 import AxisViewer from "../objects/tool/AxisViewer.js";
  
-  
+   
 
 import {ExtendScene} from '../../viewer/ExtendScene.js' 
 import {transitions, easing, lerp} from '../utils/transitions.js' 
@@ -131,7 +131,7 @@ export class Viewer extends ViewerBase{
                 SiteModel,
                 volumeComputer: new VolumeComputer //暂时
             }
-            Potree.settings.useDepthTex = false
+            Potree.settings.useDepthTex = Potree.settings.mergeType2
             
             if(Potree.settings.editType == "pano" ){
                 this.modules.PanoEditor = PanoEditor
@@ -183,7 +183,12 @@ export class Viewer extends ViewerBase{
         this.visible = true
         this.fpVisiDatasets = []
         this.atDatasets = []
-        this.objs = new THREE.Object3D
+        this.objs = new THREE.Object3D, 
+        this.objs.name = 'objs'
+        this.objs.addEventListener('isVisible',()=>{
+            this.setAllTilesets(model=> model.visiChangeCallback() ) 
+        })
+        
         
         this.testMaxNodeCount = 0
         this.tiles3dVisiVCount = 0
@@ -754,43 +759,8 @@ export class Viewer extends ViewerBase{
         
          
         
-        if(Potree.settings.editType != 'pano' && Potree.settings.editType != 'merge'){
-              
-            this.addEventListener('switchFloorplanSelect',(e)=>{//进入平面图设置后 切换选中的数据集
-                this.selectedFloorplan = e.pointcloud;  //绝对显示
-                this.updateFpVisiDatasets()
-                let pointclouds;
-                if(e.pointcloud){
-                    pointclouds = [e.pointcloud]
-                }else if(this.fpVisiDatasets.length){
-                    pointclouds = this.fpVisiDatasets
-                }
-                
-                pointclouds && this.mapViewer.fitToDatasets(pointclouds) 
-                
-            })
-            
-            
-            
-            
-
-            this.modules.SiteModel.bus.addEventListener('FloorChange',(e)=>{
-                 this.updateFpVisiDatasets()
-                 this.updatePanosVisibles(e.currentFloor)       //问:编辑空间模型时,需不需要改为显示当前选择的楼层。因为若所在楼层和选中的不一致,修改选中楼层的轮廓却改不了marker显示很奇怪,尤其刚好在一个建筑内时。
-            }) 
-            this.mapViewer.mapLayer.addEventListener('floorplanLoaded',()=>{
-                 this.updateCadVisibles(this.fpVisiDatasets, true)   //加载完成后重新更新下
-            })
-                
-            /* this.modules.Clip.bus.addEventListener('updateSelectedDatasets',()=>{
-                 this.updateFpVisiDatasets()
-            }) */
-                
-            
-        }
-        
         
-        {  
+        if(Potree.settings.editType != 'pano' && Potree.settings.editType != 'merge' || Potree.settings.mergeType2){  
             let updated, zoomLevel
             let update = (e)=>{ 
                 if(e.type == 'updateModelBound' || e.viewport == this.mainViewport && (e.changeInfo.positionChanged || zoomLevel != this.images360.zoomLevel)){ 
@@ -798,9 +768,9 @@ export class Viewer extends ViewerBase{
                     //e.changeInfo.positionChanged && shelterHistory.clear() //清空
                     (e.type == 'updateModelBound' || e.changeInfo.positionChanged) && this.updateDatasetAt()  //更新所在数据集  
                     
-                    if(Potree.settings.ifShowMarker && Potree.settings.editType != 'merge'){
+                    if(Potree.settings.ifShowMarker ){
                        
-                        Common. intervalTool.isWaiting('updateMarkerVisibles', ()=>{  
+                        Common.intervalTool.isWaiting('updateMarkerVisibles', ()=>{  
                             if(!this.mainViewport.view.isFlying() ){ 
                                 this.updateMarkerVisibles()  
                             }    
@@ -809,6 +779,7 @@ export class Viewer extends ViewerBase{
                 }
                 
             }
+            
             this.addEventListener('camera_changed', update) 
             this.addEventListener('updateModelBound', update) 
 
@@ -838,6 +809,46 @@ export class Viewer extends ViewerBase{
             
             
         } 
+        
+        
+        
+        if(Potree.settings.editType != 'pano' && Potree.settings.editType != 'merge'){
+              
+            this.addEventListener('switchFloorplanSelect',(e)=>{//进入平面图设置后 切换选中的数据集
+                this.selectedFloorplan = e.pointcloud;  //绝对显示
+                this.updateFpVisiDatasets()
+                let pointclouds;
+                if(e.pointcloud){
+                    pointclouds = [e.pointcloud]
+                }else if(this.fpVisiDatasets.length){
+                    pointclouds = this.fpVisiDatasets
+                }
+                
+                pointclouds && this.mapViewer.fitToDatasets(pointclouds) 
+                
+            })
+            
+            
+            
+            
+
+            this.modules.SiteModel.bus.addEventListener('FloorChange',(e)=>{
+                 this.updateFpVisiDatasets()
+                 this.updatePanosVisibles(e.currentFloor)       //问:编辑空间模型时,需不需要改为显示当前选择的楼层。因为若所在楼层和选中的不一致,修改选中楼层的轮廓却改不了marker显示很奇怪,尤其刚好在一个建筑内时。
+            }) 
+            this.mapViewer.mapLayer.addEventListener('floorplanLoaded',()=>{
+                 this.updateCadVisibles(this.fpVisiDatasets, true)   //加载完成后重新更新下
+            })
+                
+            /* this.modules.Clip.bus.addEventListener('updateSelectedDatasets',()=>{
+                 this.updateFpVisiDatasets()
+            }) */
+                
+            
+        }
+        
+        
+        
         { 
             let interval 
             document.addEventListener('visibilitychange',(e)=>{ 
@@ -4886,20 +4897,9 @@ export class Viewer extends ViewerBase{
 		this.update(deltaTime, timestamp);
         this.magnifier.render();
         this.render(); 
-          
-        
-        this.objs.children.forEach(e=>{
-            if(e.fileType == '3dTiles'){
-                e.traverse(child=>{
-                    if(child.runtime){
-                        child.runtime.update(deltaTime, this.renderer, this.mainViewport.camera)
-                        return {stopContinue:true}
-                    }
-                })
-                
-            }
-        }) 
-         
+           
+        this.setAllTilesets(model=>model.runtime.update(deltaTime, this.renderer, this.mainViewport.camera))
+       
         
 		// let vrActive = viewer.renderer.xr.isPresenting;
 		// if(vrActive){
@@ -5301,11 +5301,10 @@ export class Viewer extends ViewerBase{
                     } 
                     if(fileInfo_.useStandandMat && !(child.material instanceof THREE.MeshStandardMaterial)){
                         child.material = new THREE.MeshStandardMaterial()
+                        child.material.roughness = 0.7
+                        child.material.metalness = 0.5
                     } 
-                    if(child.material instanceof THREE.MeshStandardMaterial){
-                        /* child.material.roughness = 0.7
-                        child.material.metalness = 0.5  */
-                    }
+                     
                     //纯色的还是不能用BasicMaterial
                 } 
             } );
@@ -5470,14 +5469,21 @@ export class Viewer extends ViewerBase{
                     get: function() {
                         return vi 
                     },
-                    set: function(v) {
+                    set: function(v) { 
                         vi = v 
-                        tileset.visible = v;  //同步,使不加载
-                        tileset.nextForceUpdate = true
+                        result.model.visiChangeCallback()
                     }  
                 })  
-            } 
-            
+            }
+            let v = true
+            result.model.visiChangeCallback = ()=>{
+                let visi = result.model.realVisible()
+                tileset.visible = visi;  //同步,使不加载 
+                if(v != visi){
+                    tileset.nextForceUpdate = true
+                    v = visi
+                }
+            }
             loadDone(result.model/* , null, fileInfo.url */) 
             
         }else if(fileInfo.fileType == 'dxf'){
@@ -5485,16 +5491,16 @@ export class Viewer extends ViewerBase{
                 loadDone(object)
             },fileInfo) 
         }else if(fileInfo.fileType == 'shp'){
-             
-            loaders.shapeLoader.transform = viewer.transform.lonlatToLocal;
-             
-            const shp = await loaders.shapeLoader.load(fileInfo.url);
+            if(viewer.transform){
+                loaders.shapeLoader.transform = viewer.transform.lonlatToLocal;
+            }
+            const shp = await loaders.shapeLoader.load(fileInfo.url, fileInfo.color);
             const shpModel = shp.node
             
             loadDone(shpModel)
             
         }else if(fileInfo.fileType == '3dgs'){
-            
+             
             const gsViewer = new GaussianSplats3D.Viewer({ 
                 rootElement: this.renderArea,
                 threeScene: this.scene.scene,
@@ -5502,7 +5508,7 @@ export class Viewer extends ViewerBase{
                 camera:  this.mainViewport.camera,
                 useBuiltInControls: false,
                 //dropInMode: true,
-                 sharedMemoryForWorkers:false  //否则 报错 Uncaught (in promise) DOMException: Failed to execute 'postMessage' on 'DedicatedWorkerGlobalScope': SharedArrayBuffer transfer requires self.crossOriginIsolated. 
+                // sharedMemoryForWorkers:false  //否则 报错 Uncaught (in promise) DOMException: Failed to execute 'postMessage' on 'DedicatedWorkerGlobalScope': SharedArrayBuffer transfer requires self.crossOriginIsolated. 
 
             });
             //let path = Potree.resourcePath+'/models/gaussian/bonsai.ksplat';
@@ -5521,10 +5527,10 @@ export class Viewer extends ViewerBase{
                     //viewer.mainViewport.view.setView({position: new THREE.Vector3(-4.980,  -5.3879,  5.4503095), quaternion:new THREE.Quaternion(0.5750,-0.2809,-0.3372,0.6903)})
                 
                     gsViewer.splatMesh.onSplatTreeReadyCallback = ()=>{ 
+                        loadDone(gsViewer.splatMesh)
                         let {sceneMax,sceneMin} = gsViewer.splatMesh.splatTree.subTrees[0]
                         gsViewer.splatMesh.boundingBox.min.copy(sceneMin)
-                        gsViewer.splatMesh.boundingBox.max.copy(sceneMax)
-                        loadDone(gsViewer.splatMesh)
+                        gsViewer.splatMesh.boundingBox.max.copy(sceneMax) 
                     } 
                 });
             
@@ -5563,21 +5569,33 @@ export class Viewer extends ViewerBase{
     }
     
     
-     
     
-    setDisplay(state, cause='setDisplay'){//如果创建了iframe,主页的需要隐藏的话需要释放一些内存出来。iframe关闭前也释放下比较保险
-        state = !!state
+    setAllTilesets(fun){//让所有tileset执行fun。    objs.children中的3dtiles最多两层tileset
         this.objs.children.forEach(e=>{
             if(e.fileType == '3dTiles'){
-                let tileset = e.runtime.getTileset()
-                Potree.Utils.updateVisible(e,  cause, state)
-                if(!state) tileset._cache.trim(); //使下一次update时dispose所有不可见的tiles
-                e.runtime.update(16, this.renderer, this.mainViewport.camera, true)
-                if(state) this.dispatchEvent('content_changed')
+                e.traverse(child=>{
+                    if(child.runtime){
+                        fun(child)
+                        return {stopContinue:true}
+                    }
+                })
+                
             }
+        }) 
+    }
+     
+    
+    setDisplay(state, cause='setDisplay'){//如果创建了iframe,主页的需要隐藏的话需要释放一些内存出来。iframe关闭前也释放下比较保险
+        state = !!state
+      
+        this.setAllTilesets(model=>{
+            let tileset = model.runtime.getTileset()
+            Potree.Utils.updateVisible(model, cause, state)
+            if(!state) tileset._cache.trim(); //使下一次update时dispose所有不可见的tiles
+            model.runtime.update(16, this.renderer, this.mainViewport.camera, true)
+            if(state) this.dispatchEvent('content_changed') 
         })
         
-        
         if(state){
             Potree.pointBudget = 6*1000*1000 //先随便写一个, 随后mergeEditor.updateMemoryUsage
         }else{

+ 5 - 2
src/custom/viewer/map/Map.js

@@ -352,7 +352,10 @@ export class TiledMapBase extends THREE.EventDispatcher{
         
         var c = this.tileSizePx / i.length() / scale      //多除以一个scale缩放因子,scale越大level越小
           , level = Math.ceil(-Math.log(c) / Math.log(2) - this.bias);
-         
+        
+        if(this.style == 'dark-standard'){ //该模式贴图比较小放大点
+            level -= 1
+        } 
         level = Math.max(level, 0) 
         level = Math.min(level, void 0 === this.maxDepth ? 1 / 0 : this.maxDepth)  
         
@@ -811,7 +814,7 @@ export class TiledMapOpenStreetMap extends TiledMapBase{
                 if(style == 'satellite'){//卫星
                     this.maxDepth = 18
                     this.baseUrl = "https://webst01.is.autonavi.com/appmaptile?lang=zh_cn&style=6&yrs=m&x=${x}&y=${y}&z=${z}"
-                }else if(style == 'roads'){
+                }else if(style == 'dark-standard'){
                     this.maxDepth = 18
                     this.baseUrl = "https://wprd01.is.autonavi.com/appmaptile?lang=zh_cn&style=8&yrs=m&x=${x}&y=${y}&z=${z}"    //路网   加上scl=2后去掉名字
                 }else{

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

@@ -765,7 +765,7 @@ export class MapViewer extends ViewerBase{
         
         
         //绘制其他物体
-        Potree.Utils.setCameraLayers(this.camera, ['mapObjects'  , 'bothMapAndScene'  ])
+        Potree.Utils.setCameraLayers(this.camera, ['mapObjects'  , 'bothMapAndScene', 'light'  ])
         viewer.dispatchEvent({type: "render.begin",  viewer: this, viewport:this.viewports[0], params }); 
         
         this.attachedToViewer || renderer.render(viewer.scene.scene, this.camera); //类同renderOverlay

+ 5 - 0
src/navigation/FirstPersonControlsNew.js

@@ -579,6 +579,11 @@ export class FirstPersonControls extends THREE.EventDispatcher {
     }
     setEnable(enabled){
         this.enabled = enabled;
+        if(!enabled){
+            this.yawDelta = this.pitchDelta = 0
+            this.translationDelta.set(0,0,0)
+            this.translationWorldDelta.set(0,0,0)
+        }
          
     }
     setTarget(target, index){//绕该点旋转,类似orbitControl

+ 6 - 0
src/viewer/sidebar2.html

@@ -25,6 +25,12 @@
                     <li name="3dTiles">
                         3dTiles : <button name='operation'>添加</button>  <button name='select'> select </button>
                     </li>
+                    <li name="3dgs">
+                        3dgs : <button name='operation'>添加</button>  <button name='select'> select </button>
+                    </li>
+                    <li name="shp">
+                        shape : <button name='operation'>添加</button>  <button name='select'> select </button>
+                    </li>
                 </ul>
                 
                 <li> <button name='splitScreen'>分屏</button> </li>