123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365 |
-
- import * as THREE from "../../../libs/three.js/build/three.module.js";
- import SplitScreen from "./SplitScreen.js";
- const viewportProps = [
- {
- left:0.5,
- bottom:0.5,
- width: 0.5,height:0.5,
- name : 'MainView',
- //view: viewer.scene.view,
- active: true,
- },
- {
- left:0,
- bottom:0.5,
- width: 0.5,height:0.5,
- name : 'top',
- name2 : 'mapViewport',
- axis:["x","y"],
- direction : new THREE.Vector3(0,0,-1), //镜头朝向
- //axisSign:[1,1],
- active: true,
- //相机位置在z轴正向
- },
- {
- left:0.5,
- bottom:0,
- width: 0.5,height:0.5,
- name : 'right',
- axis:["y","z"],
- direction : new THREE.Vector3(1,0,0),
- //axisSign:[1,1],
- active: true,
- //相机位置在x轴负向 右下角屏
- },
- {
- left:0,
- bottom:0,
- width: 0.5,height:0.5,
- name : 'back',
- axis:["x","z"],
- direction : new THREE.Vector3(0,-1,0),
- //axisSign:[-1,1], // 从镜头方向看 x向左 所以取负
- active: true,
- //相机位置在y轴正向 左下角屏
- },
- ]
- var SplitScreen4Views = new SplitScreen()
-
-
- SplitScreen4Views.split = function(o={}){
- var defaultCamera = viewer.scene.getActiveCamera()
-
- let {boundSize, center} = viewer.bound
-
- viewer.setLimitFar(false)
- viewer.mapViewer.attachToMainViewer(true,'split4Screens','dontSet')
-
- let viewports = this.splitStart(viewportProps)
-
- //覆盖在map上、点云等其他物体之下的一层背景
- let mapViewport = viewer.mapViewer.viewports[0]
- mapViewport.noPointcloud = false
- //隐藏地图游标
- //Potree.Utils.updateVisible(viewer.mapViewer.cursor, 'split4Screens', false)
- /* viewer.images360.panos.forEach(pano=>{
- Potree.Utils.updateVisible(pano.mapMarker, 'split4Screens', false) //希望这时候mapMarker已经建好了吧
- }) */
-
-
- /* viewer.images360.panos.forEach(pano=>{
- pano.addLabel2()
- Potree.Utils.updateVisible(pano.label2, 'notDisplay', true)
- pano.dispatchEvent({type:'changeMarkerTex',name:'ring'})
- }) */
-
- //材质
- this.statesBefore = {
- pointDensity : Potree.settings.pointDensity,
- displayMode : Potree.settings.displayMode,
-
- position: viewer.images360.position,
- target: viewer.scene.view.getPivot(),
- currentPano: viewer.images360.currentPano,
-
- //---
- //ifShowMarker : Potree.settings.ifShowMarker,
- }
-
- viewer.setPointStandardMat(true,null,true) //切换到标准模式(主要为了mainViewport) 点云使用标准大小
-
- var matBefore = {
- opacity : new Map()
- }
- var newOpacityMap = new Map()
-
- viewer.scene.pointclouds.forEach(e=>{
- matBefore.opacity.set(e, e.temp.pointOpacity)
- matBefore.colorType = e.material.activeAttributeName
-
- /* {
- var map = new Map()
- newOpacityMap.set(e, map )
- var size = e.bound.getSize()
- viewports.forEach(viewport=>{//根据bound设置opacity,越小的要靠越近,需要大的opacity。但似乎影响太大了
- if(viewport.name == 'MainView')return;
- var prop = viewportProps.find(v => viewport.name == v.name2||viewport.name == v.name)
- let axis = prop.axis
- var width = size[axis[0]]
- var height = size[axis[1]]
- var area = width * height
- map.set(viewport, 5000/area);
- })
-
- } */
- })
-
- let beforeRender = function(){
- viewer.scene.pointclouds.forEach(e=>{
- if(this.name == "MainView"){
- e.material.activeAttributeName = matBefore.colorType // 'rgba'
-
- e.material.useFilterByNormal = false
- e.changePointOpacity(matBefore.opacity.get(e)) //1 //恢复下 e.temp.pointOpacity 其实就是1
-
- Potree.settings.pointDensity = 'fourViewportsMain'/* 'fourViewports' */ //本来想比另外三屏高一点质量,结果发现会闪烁,因为点云加载需要时间 (navvis仿版也是一样,以后看看能否优化)
-
- }else{
- e.material.activeAttributeName = "color"
- e.material.useFilterByNormal = true
-
- Potree.settings.pointDensity = 'fourViewports' //强制降低点云质量
-
- //侧面重叠概率更大,所以透明度调小
- e.changePointOpacity(this.name == "mapViewport" ? 0.2 : 0.06/* newOpacityMap.get(e).get(viewport), true */); //多数据集有的数据集很小,放大后显示特别淡
- //console.log(e.name, viewport.name, e.temp.pointOpacity, e.material.opacity)
- }
-
-
- viewer.images360.panos.forEach(pano=>{
- if(this.name == 'mapViewport'){
- Potree.Utils.updateVisible(pano.marker, 'showOnMap', true, 1, 'add' )
- }else{
- Potree.Utils.updateVisible(pano.marker, 'showOnMap', false, 1, 'cancel' )
- }
- })
-
-
- })
- }
- viewports.forEach(viewport=>{viewport.beforeRender = beforeRender})
-
-
-
- this.enableMap(false)
- this.enableFloorplan(false)
- viewer.mapViewer.setViewLimit('expand') //多数据集距离远时可以任意远,所以不限制了。但是这样就会看到地图边界了怎么办?
- //viewer.dispatchEvent({'type': 'beginSplitView' })
- //viewer.updateScreenSize({forceUpdateSize:true})
-
-
-
- //this.viewportFitBound(mapViewport, boundSize, center)
- //Potree.settings.ifShowMarker = false
- Potree.settings.displayMode = 'showPointCloud'
- }
-
-
- SplitScreen4Views.recover = function(){
- this.unSplit()
- viewer.mapViewer.viewports[0].beforeRender = null;
- /* const {width, height} = viewer.renderer.getSize(new THREE.Vector2());
- viewer.renderer.setViewport(0,0,width,height)
- viewer.renderer.setScissorTest( false ); */
-
- viewer.setView({
- position: this.statesBefore.position,
- target: this.statesBefore.target,
- currentPano: this.statesBefore.currentPano,
- duration:300,
- callback:function(){
- }
- })
-
-
-
- viewer.mainViewport.beforeRender = null
- viewer.setLimitFar(true)
-
- let mapViewport = viewer.mapViewer.viewports[0]
- viewer.mapViewer.attachToMainViewer(false)
- //Potree.Utils.updateVisible(viewer.mapViewer.cursor, 'split4Screens', true)
- /* viewer.images360.panos.forEach(pano=>{
- Potree.Utils.updateVisible(pano.mapMarker, 'split4Screens', true)
- }) */
-
- /* viewer.images360.panos.forEach(pano=>{
- Potree.Utils.updateVisible(pano.label2, 'notDisplay', false )
- pano.dispatchEvent({type:'changeMarkerTex',name:'default'})
- }) */
-
- mapViewport.noPointcloud = true
- {
- this.enableMap(Potree.settings.mapEnable)
- this.enableFloorplan(Potree.settings.floorplanEnable)
- if(this.floorplanListener){
- viewer.mapViewer.mapLayer.removeEventListener( 'floorplanLoaded', this.floorplanListener )
- this.floorplanListener = null
- }
- }
-
- Potree.settings.pointDensity = this.statesBefore.pointDensity
- if(!Potree.settings.isOfficial){
- Potree.settings.displayMode = this.statesBefore.displayMode
- }
-
- viewer.scene.pointclouds.forEach(e=>{
- //e.material.color.set(this.statesBefore.mat.color)
- //e.material.activeAttributeName = this.statesBefore.mat.colorType
- e.material.useFilterByNormal = false
- //e.material.opacity = this.statesBefore.mat.opacity
- })
- viewer.setPointStandardMat(false)
- viewer.mapViewer.setViewLimit('standard')
-
- viewer.images360.panos.forEach(pano=>{
- Potree.Utils.updateVisible(pano.marker, 'showOnMap', false, 1, 'cancel' )
- })
- //Potree.settings.ifShowMarker = this.statesBefore.ifShowMarker
- //viewer.dispatchEvent({'type': 'finishSplitView' })
- //viewer.updateScreenSize({forceUpdateSize:true})
-
- }
-
- SplitScreen4Views.updateMapViewerBG = function(){
- let mapViewport = viewer.mapViewer.viewports[0]
- if( this.floorplanEnabled || this.mapEnabled){
- mapViewport.background = 'overlayColor'
- mapViewport.backgroundColor = new THREE.Color(0,0,0)
- mapViewport.backgroundOpacity = 0.5;
- }else{
- mapViewport.background = null
- mapViewport.backgroundColor = null
- mapViewport.backgroundOpacity = null
- }
- viewer.mapViewer.mapChanged = true
- viewer.mapViewer.needUpdate = true
- }
- SplitScreen4Views.setFloorplanDisplay = function(e, show=false){
- e.floorplan.setEnable(show)
- }
-
- SplitScreen4Views.enableMap = function(enable){
- let map = viewer.mapViewer.mapLayer.maps.find(e=>e.name == 'map')
- map.setEnable(!!enable)
-
- //viewer.mapViewer.mapGradientBG = viewer.background == 'gradient' && !enable
- this.mapEnabled = enable
- this.updateMapViewerBG()
-
-
-
- },
- //直接覆盖原设置
- SplitScreen4Views.enableFloorplan = function(enable){ //是否让自定义的平面图显示
- let floorplans = viewer.mapViewer.mapLayer.maps.filter(e=>e.name.includes('floorplan'))
-
- if(this.floorplanListener){
- viewer.mapViewer.mapLayer.removeEventListener( 'floorplanLoaded', this.floorplanListener )
- }
- this.floorplanListener = (e)=>{
- this.setFloorplanDisplay(e, enable)
- }
-
- viewer.mapViewer.mapLayer.addEventListener( 'floorplanLoaded', this.floorplanListener ) //万一之后才加载
-
-
- if(!enable){
- //隐藏平面图
- floorplans.forEach(floorplan=>this.setFloorplanDisplay({floorplan},false))
-
- }else{
-
- floorplans.forEach(floorplan=>this.setFloorplanDisplay({floorplan},true))
-
- }
-
-
- if (enable && floorplans.length == 0) Potree.loadMapEntity('all',true)
-
- this.floorplanEnabled = enable
- this.updateMapViewerBG()
- },
- /* viewportFitBound:function(viewport, boundSize, center){ //使一个viewport聚焦在某个范围
- var prop = viewportProps.find(v => viewport.name == v.name2||viewport.name == v.name)
- let axis = prop.axis
- let expand = 10;
- let position = center.clone()
- var moveAtAxis = ['x','y','z'].find(e=>!(axis.includes(e)))
-
- if(viewport.name == 'mapViewport'){
- let ori = viewport.view.position[moveAtAxis]
- position[moveAtAxis] = ori //不改变这个值,尤其是mapViewer中的z
- }else{
- position[moveAtAxis] += boundSize[moveAtAxis]/2+expand//移动到bounding边缘外
- }
-
- viewport.view.position.copy(position)
-
- var width = Math.max(boundSize[axis[0]], boundSize[axis[1]] * viewport.camera.aspect)//视口宽度(米)
- var margin = 50 //px
- viewport.camera.zoom = (viewport.resolution.x - margin) / width
- viewport.camera.updateProjectionMatrix()
- },
- */
-
- SplitScreen4Views.focusOnPointCloud = function(pointcloud){//三个屏都聚焦在这个点云
- var boundSize = pointcloud.bound.getSize(new THREE.Vector3);
- var center = pointcloud.bound.getCenter(new THREE.Vector3);
- let target = pointcloud.panosBound && pointcloud.panosBound.center //看向pano集中的地方,也就是真正有点云的地方。(因为需要展示所有点云,所以没办法用这个做为center)
- this.focusOnObject(pointcloud.bound, center,target)
-
- viewer.flyToDataset({pointcloud, dontMoveMap:true, duration:0})
- }
- SplitScreen4Views.focusOnObject = function(bound, center, target, duration=0){
- viewer.viewports.forEach(e=>{
- if(e.name == 'MainView'){
- /* let len = boundSize.length()
- let distance = THREE.Math.clamp(e.view.position.distanceTo(center), len * 0.01, len*0.3 ) //距离限制
- //viewer.focusOnObject({position:center}, 'point', duration, {distance, direction: e.view.direction,dontMoveMap:true} )//平移镜头
- //为了方便定位,直接飞到中心位置:
- e.view.setView({
- position:center, duration, target
- }) */
- }else{
- this.viewportFitBound(e, bound, center)
- }
- })
- }
-
-
- export default SplitScreen4Views
|