123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224 |
- import {ExtendView} from "../../viewer/ExtendView.js";
- import Viewport from "../viewer/Viewport.js";
- import * as THREE from "../../../libs/three.js/build/three.module.js";
-
-
- class SplitScreen extends THREE.EventDispatcher{
- constructor (args = {}) {
- super();
-
- }
- /*
- viewport.targetPlane // bound中心点处的plane,方向和view一致
- viewport.shiftTarget // camera的位置project在targetPlane上的位置
- 这两个参数的主要目的是为了getPosOutOfModel,以及rotateSideCamera时保持相对位置
- */
- splitStart(cameraProps){
- this.splited = true
- let viewports = []
-
- let subViewports = [viewer.mainViewport]
- if(viewer.mapViewer){
- subViewports.push(viewer.mapViewer.viewports[0])
- }
-
- let length = cameraProps.length
- for(let i=0;i<length;i++){
- let prop = cameraProps[i];
- let viewport;
- let v = subViewports.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){
- let view = new ExtendView()
- if(prop.limitBound)view.limitBound = prop.limitBound
- prop.direction && (view.direction = prop.direction)
-
- viewport = new Viewport(view , this.getOrthoCamera(), prop )
- if(prop.viewContainsPoints)viewport.viewContainsPoints = prop.viewContainsPoints
-
- //viewport.unableDepth = true //depthBasicMaterial等在此viewport中不开启depth
-
- }
- if(viewport.camera.type == 'OrthographicCamera' ){
- viewport.targetPlane = new THREE.Plane()
- viewport.shiftTarget = new THREE.Vector3 //project在targetPlane上的位置
- }
- viewport.fitMargin = prop.margin
- viewports.push(viewport)
- }
- viewer.viewports = viewports;
- viewer.updateScreenSize({forceUpdateSize:true})
- viewports.forEach(viewport=>{
- if(viewport.name == 'MainView')return
- this.viewportFitBound(viewport, viewer.bound.boundingBox , viewer.bound.center , 0, viewport.fitMargin)
- })
- return viewports
- }
-
-
- unSplit(){
- this.splited = false
- this.unfocusViewport()
- viewer.inputHandler.hoverViewport = null //清空
- viewer.viewports = [viewer.mainViewport]
- viewer.mainViewport.width = 1;
- viewer.mainViewport.height = 1;
- viewer.mainViewport.left = 0
- viewer.mainViewport.bottom = 0;
- viewer.updateScreenSize({forceUpdateSize:true})
- }
-
- viewportFitBound(viewport, bound, center, duration=0, margin){
- let view = viewport.view
- let info = {bound}
-
- let {boundSize, boundCenter} = this.getViewBound(viewport, bound )
-
- //this.setShiftTarget(viewport, boundCenter)
-
- viewport.targetPlane.setFromNormalAndCoplanarPoint( view.direction.clone(), boundCenter )
- viewport.targetPlane.projectPoint(center, viewport.shiftTarget) //target转换到过模型中心的平面,以保证镜头一定在模型外 this.shiftTarget是得到的
-
- info.endPosition = this.getPosOutOfModel(viewport, boundSize)
-
- //if(viewport.name == 'mapViewport')info.endPosition.z = Math.max(Potree.config.map.cameraHeight, info.endPosition.z)
-
- info.margin = margin || {x:30, y:30}
- view.moveOrthoCamera(viewport, info , duration )
- }
-
-
- getViewBound(viewport, boundingBox){
- if(boundingBox){
- boundSize = boundingBox.getSize(new THREE.Vector3)
- center = boundingBox.getCenter(new THREE.Vector3)
- }else{
- var {boundSize, center, boundingBox} = viewer.bound
- }
-
-
- let containsPoints = []
- this.focusCenter && containsPoints.push(this.focusCenter)
- viewport.viewContainsPoints && containsPoints.push(...viewport.viewContainsPoints)
-
- if(containsPoints.length){//视野范围内必须要包含的点,直接算入模型区域。这时候得到的boundCenter和模型中心不重合
- boundingBox = boundingBox.clone()
- containsPoints.forEach(point=>{
- boundingBox.expandByPoint(point)
- })
- boundSize = boundingBox.getSize(new THREE.Vector3)
- center = boundingBox.getCenter(new THREE.Vector3)
- }
-
- return {boundSize, boundCenter:center }
- }
-
- getPosOutOfModel(viewport, boundSize){
- //let {boundSize, center} = viewer.bound
- boundSize = boundSize || this.getViewBound(viewport).boundSize
- let expand = 10;
- let radius = boundSize.length() * 2
- let position = viewport.shiftTarget.clone().sub(viewport.view.direction.clone().multiplyScalar(radius + expand))
-
- return position
- }
-
- updateCameraOutOfModel(){//因为移动模型导致模型超出相机外,所以更新位置
- viewer.viewports.forEach((viewport, i )=>{
- if(viewport.camera.isOrthographicCamera){ //or if(viewport.targetPlane)
- let {boundSize, boundCenter} = this.getViewBound(viewport)
- /* viewport.targetPlane.setFromNormalAndCoplanarPoint( viewport.view.direction.clone(), boundCenter)
- viewport.targetPlane.projectPoint(viewport.view.position, viewport.shiftTarget) //target转换到过模型中心的平面,以保证镜头一定在模型外 this.shiftTarget是得到的
- */
- this.setShiftTarget(viewport, boundCenter)
- let endPosition = this.getPosOutOfModel(viewport, boundSize)
- //if(viewport.name == 'mapViewport')endPosition.z = Math.max(Potree.config.map.cameraHeight, endPosition.z)
- viewport.view.position.copy(endPosition)
- }
- })
- }
-
-
-
-
- setShiftTarget(viewport, center){
- if(!viewport.targetPlane ){
- viewport.targetPlane = new THREE.Plane()
- viewport.shiftTarget = new THREE.Vector3 //project在targetPlane上的位置
- }
-
- viewport.targetPlane.setFromNormalAndCoplanarPoint(viewport.view.direction, center )
- viewport.targetPlane.projectPoint(viewport.view.position, viewport.shiftTarget ) //target转换到过模型中心的平面,以保证镜头一定在模型外
-
- }
-
- rotateSideCamera(viewport, angle){//侧视图或俯视图绕模型中心水平旋转
-
- //let {boundSize, center} = viewer.bound
- let {boundSize, boundCenter } = this.getViewBound(viewport)
- let center = this.focusCenter || boundCenter //旋转中心,一般是所有模型的中心,除非想指定中心点
- this.setShiftTarget(viewport, center)
- //找到平移向量
- let vec = new THREE.Vector3().subVectors(center, viewport.shiftTarget)//相对于中心的偏移值,旋转后偏移值也旋转
-
- //旋转
- var rotMatrix = new THREE.Matrix4().makeRotationAxis(new THREE.Vector3(0,0,1), angle)
-
- viewport.view.direction = viewport.view.direction.applyMatrix4(rotMatrix)
-
-
- vec.applyMatrix4(rotMatrix)
- viewport.shiftTarget.subVectors(center,vec) //新的
-
-
- viewport.view.position = this.getPosOutOfModel(viewport, boundSize)
-
- }
-
- getOrthoCamera(){
- let camera = new THREE.OrthographicCamera(-100, 100, 100, 100, 0.01, 10000)
- camera.up.set(0,0,1)
- return camera
- }
-
- focusOnViewport(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(){
- 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
- }
-
- }
- export default SplitScreen
|