|
@@ -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{
|