123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339 |
- import {View} from "../viewer/View.js";
- import Viewport from "../viewer/Viewport.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"],
- //axisSign:[1,1],
- active: true,
- },
- {
- left:0.5,
- bottom:0,
- width: 0.5,height:0.5,
- name : 'Right',
- axis:["y","z"],
- //axisSign:[1,1],
- active: true,
- },
- {
- left:0,
- bottom:0,
- width: 0.5,height:0.5,
- name : 'Back',
- axis:["x","z"],
- //axisSign:[-1,1], // 从镜头方向看 x向左 所以取负
- active: true,
- },
- ]
- var SplitScreen = {
-
- //viewer.modules.Alignment.SplitScreen.viewportFitBound(viewer.mapViewer.viewports[0],viewer.bound.boundSize, viewer.bound.center)
-
- splitScreen4Views : function(o={}){
- var defaultCamera = viewer.scene.getActiveCamera()
-
- let {boundSize, center} = viewer.bound
-
- var getOrthographicCamera = function(widthRatio, heightRatio, axis){
- var widthPX = viewer.renderArea.clientWidth * widthRatio;
- var heightPX = viewer.renderArea.clientHeight * heightRatio;
- var aspect = widthPX/heightPX
- console.log(viewer.renderArea.clientWidth,viewer.renderArea.clientHeight,aspect)
- var width = Math.max(boundSize[axis[0]], boundSize[axis[1]] * aspect)
- var orthographicCamera = new THREE.OrthographicCamera(-widthPX/2, widthPX/2, heightPX/2, -heightPX/2, 0.01, 10000);
- var margin = 50 //px
- orthographicCamera.zoom = (widthPX - margin) / width//zoom越大视野越小
- var moveAtAxis = ['x','y','z'].find(e=>!(axis.includes(e)))
- orthographicCamera.up.set(0,0,1)
- orthographicCamera.position.copy(center)
- orthographicCamera.position[moveAtAxis] += 1000;//偏移一些 在模型外即可
-
-
-
-
- return orthographicCamera
- }
-
-
-
- //材质
- let material = viewer.scene.pointclouds[0].material
- this.statesBefore = {
- mat : {
- colorType : material.activeAttributeName,
- color : material.color.clone(),
- opacity : material.opacity,
- },
- pointDensity : Potree.settings.pointDensity,
- displayMode : Potree.settings.displayMode,
- }
-
-
- let beforeRender = function(viewport){
- viewer.scene.pointclouds.forEach(e=>{
- if(viewport.name == "MainView"){
- e.material.activeAttributeName = SplitScreen.statesBefore.mat.colorType
- e.material.color.copy(SplitScreen.statesBefore.mat.color)
- e.material.useFilterByNormal = false
- e.material.opacity = SplitScreen.statesBefore.mat.opacity
- Potree.settings.pointDensity = 'fourViewports' //本来想比另外三屏高一点质量,结果发现会闪烁,因为点云加载需要时间 (navvis仿版也是一样,以后看看能否优化)
- }else{
- e.material.activeAttributeName = "color"
- e.material.color.set(e.color)
- e.material.useFilterByNormal = true
- e.material.opacity = /* THREE.Math.clamp( */e.material.spacing /* , 0.01,100); */ //0.09 //越稀疏给的opacity应该越高,支持超过1(隧道场景 spacing达9之多)
- Potree.settings.pointDensity = 'fourViewports' //强制降低点云质量
- }
- })
- }
-
-
-
- let viewports = []
-
- //更改mainViewport参数
- viewports.push(viewer.mainViewport)
-
- let mapViewport = viewer.mapViewer.viewports[0]
- viewports.push(mapViewport)
-
-
-
-
-
-
- for(let i=0;i<4;i++){
- let prop = viewportProps[i];
- let viewport;
-
-
- let v = viewports.find(e=>e.name == (prop.name2||prop.name))
- if(v){
- viewport = v
- viewport.left = prop.left; viewport.bottom = prop.bottom; viewport.width = prop.width; viewport.height = prop.height;
- }
-
- if(!viewport){
- viewport = new Viewport( new View(), getOrthographicCamera(prop.width, prop.height, prop.axis), prop )
- viewports.push(viewport)
- }
-
-
- viewport.beforeRender = beforeRender;
-
- if(viewport.name != 'MainView'){
- viewport.view.setCubeView(viewport.name)
- viewport.view.position.copy(viewport.camera.position)
- }
-
-
- }
-
-
- viewer.viewports = viewports;
- viewer.setLimitFar(false)
-
- viewer.mapViewer.attachToMainViewer(true,'split4Screens','dontSet')
- //覆盖在map上、点云等其他物体之下的一层背景
-
- mapViewport.noPointcloud = false
- //隐藏地图游标
- viewer.updateVisible(viewer.mapViewer.cursor, 'split4Screens', false)
- viewer.images360.panos.forEach(pano=>{
- viewer.updateVisible(pano.mapMarker, 'split4Screens', false) //希望这时候mapMarker已经建好了吧
- })
-
-
-
-
- this.enableMap(false)
- this.enableFloorplan(false)
-
- //viewer.dispatchEvent({'type': 'beginSplitView' })
- viewer.updateScreenSize({forceUpdateSize:true})
- this.viewportFitBound(mapViewport, boundSize, center)
-
- Potree.settings.displayMode = 'showPointCloud'
- },
-
-
-
-
-
-
- recoverFrom4Views: function(){
-
- this.unfocusViewport()
-
- const {width, height} = viewer.renderer.getSize(new THREE.Vector2());
- viewer.renderer.setViewport(0,0,width,height)
- viewer.renderer.setScissorTest( false );
-
- viewer.scene.pointclouds.forEach(e=>{
- e.material.color.set(SplitScreen.statesBefore.mat.color)
- e.material.activeAttributeName = SplitScreen.statesBefore.mat.colorType
- e.material.useFilterByNormal = false
- e.material.opacity = SplitScreen.statesBefore.mat.opacity
- })
- viewer.viewports = [viewer.mainViewport]
- viewer.mainViewport.width = 1;
- viewer.mainViewport.height = 1;
- viewer.mainViewport.left = 0
- viewer.mainViewport.bottom = 0;
- viewer.mainViewport.beforeRender = null
- viewer.setLimitFar(true)
-
- let mapViewport = viewer.mapViewer.viewports[0]
- viewer.mapViewer.attachToMainViewer(false)
- viewer.updateVisible(viewer.mapViewer.cursor, 'split4Screens', true)
- viewer.images360.panos.forEach(pano=>{
- viewer.updateVisible(pano.mapMarker, 'split4Screens', true)
- })
- mapViewport.noPointcloud = true
-
- this.enableMap(true)
- this.enableFloorplan(true)
-
-
-
-
- Potree.settings.pointDensity = SplitScreen.statesBefore.pointDensity
- Potree.settings.displayMode = SplitScreen.statesBefore.displayMode
-
- //viewer.dispatchEvent({'type': 'finishSplitView' })
- viewer.updateScreenSize({forceUpdateSize:true})
- },
-
- focusOnViewport : function(name){//全屏
- viewer.viewports.forEach((viewport, i )=>{
- if(viewport.name == name){
- this.focusInfo = {
- name,
- left : viewport.left, bottom : viewport.bottom, height : viewport.height, width : viewport.width
- }
- viewport.left = 0; viewport.bottom = 0; viewport.height = 1; viewport.width = 1
-
- }else{
- viewport.active = false
- }
- })
-
- viewer.updateScreenSize({forceUpdateSize:true})
- },
-
- unfocusViewport:function(){
- if(!this.focusInfo)return
- viewer.viewports.forEach((viewport, i )=>{
- if(this.focusInfo.name == viewport.name){//全屏的恢复
- viewport.left = this.focusInfo.left;
- viewport.bottom = this.focusInfo.bottom;
- viewport.height = this.focusInfo.height;
- viewport.width = this.focusInfo.width;
- }
- viewport.active = true
- })
- viewer.updateScreenSize({forceUpdateSize:true})
- this.focusInfo = null
- },
-
-
-
-
- updateMapViewerBG(){
- 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
- }
- },
-
- setFloorplanDisplay: function(e, show=false){
- viewer.updateVisible(e.floorplan.objectGroup, 'splitScreen', !!show)
- },
-
-
- enableMap(enable){
- let map = viewer.mapViewer.mapLayer.maps.find(e=>e.name == 'map')
- viewer.updateVisible(map.objectGroup, 'splitScreen', !!enable)
-
- //viewer.mapViewer.mapGradientBG = viewer.background == 'gradient' && !enable
- this.mapEnabled = enable
- this.updateMapViewerBG()
- if(enable)viewer.mapViewer.mapLayer.needUpdate = true //加载地图
-
-
- },
- enableFloorplan(enable){ //是否让自定义的平面图显示
- let floorplan = viewer.mapViewer.mapLayer.maps.find(e=>e.name == 'floorplan')
- if(!enable){
- //隐藏平面图
-
- if(floorplan){
- //console.log('已经有floorplan')
- this.setFloorplanDisplay({floorplan},false)
- }else{
- viewer.mapViewer.mapLayer.addEventListener( 'floorplanLoaded', this.setFloorplanDisplay ) //万一之后才加载
- }
- }else{
- if(!floorplan){
- //???
- }else{
- this.setFloorplanDisplay({floorplan},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
- var moveAtAxis = ['x','y','z'].find(e=>!(axis.includes(e)))
- let ori = viewport.view.position[moveAtAxis]
- viewport.view.position.copy(center)
- viewport.view.position[moveAtAxis] = ori //不改变这个值,尤其是mapViewer中的z
- 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()
- },
-
- focusOnPointCloud:function(pointcloud){//三个屏都聚焦在这个点云
- var boundSize = pointcloud.bound.getSize(new THREE.Vector3);
- var center = pointcloud.bound.getCenter(new THREE.Vector3);
- viewer.viewports.forEach(e=>{
- if(e.name == 'MainView')return
- this.viewportFitBound(e, boundSize, center)
- })
-
-
- }
-
- }
- export default SplitScreen
|