123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808 |
- import * as THREE from "../../../../libs/three.js/build/three.module.js";
- import {MapLayer} from './Map.js'
- import {FirstPersonControls} from '../../../navigation/FirstPersonControlsNew.js'
- import {InputHandler} from "../../../navigation/InputHandlerNew.js";
- import {ViewerBase} from "../viewerBase.js"
- import {ExtendView} from "../../../viewer/ExtendView.js";
- import Viewport from "../Viewport.js";
- import math from "../../utils/math.js";
- //import CursorDeal from '../utils/CursorDeal.js'
- import {Images360} from '../../modules/panos/Images360.js'
- import Common from '../../utils/Common.js'
- import {transitions, easing, lerp} from "../../utils/transitions.js";
- import {config } from "../../settings.js";
- /* var centerCross = new THREE.Mesh(new THREE.SphereGeometry(1, 4, 4),new THREE.MeshBasicMaterial({
- transparent:true, color:"#ff0000", opacity:0.5
- })); */
- import CopyShader from '../../materials/postprocessing/CopyShader.js'
- import {ShaderPass} from '../../materials/postprocessing/ShaderPass.js'
- /* const mapHeight = -1000;//要比点云低。最低
- const cameraHeight = 1000; //最高 */
- const panosHeight = config.map.mapHeight + 100 //要比点云低 (marker)
- const cursorHeight = 0;//比地图高就行
- const routeLayerHeight = config.map.mapHeight + 105
- const texLoader = new THREE.TextureLoader()
- const planeGeo = new THREE.PlaneBufferGeometry(1,1)
- const markerSize = 1;
- var initCameraFeildWidth = 50
- var panoMarkerMats
-
- export class MapViewer extends ViewerBase{
- constructor(dom){
- super(dom, {
- clearColor: Potree.config.mapBG,
- name: 'mapViewer',
- antialias:true
- })
- this.visible = true
- this.initScene()
- this.needRender_ = false
-
- this.mapLayer = new MapLayer(this, this.viewports[0])
- this.scene.add(this.mapLayer.sceneGroup)
- this.mapLayer.sceneGroup.position.setZ(Potree.config.map.mapHeight)
- this.mapRatio = 0.5
- this.splitDir = 'leftRight'
- this.renderMeasure = false
-
- //因context的preserveDrawingBuffer为false之后,canvas渲染多个viewport时会自动clear,所以若不渲染就会是空的。所以没有变化时就直接拷贝buffer好了。
- this.copyPass = new ShaderPass( CopyShader );
- this.copyBuffer = new THREE.WebGLRenderTarget( 100, 100 , {
- minFilter: THREE.LinearFilter,
- magFilter: THREE.LinearFilter,
- format: THREE.RGBAFormat,
- stencilBuffer: false,
- });
-
-
-
- viewer.addEventListener("camera_changed", (e)=>{
- let needUpdateCursor
- if(e.viewport == viewer.mainViewport){
- needUpdateCursor = true
- }else if(e.viewport == this.viewports[0]){//attachedToViewer
- needUpdateCursor = true
- this.mapChanged = true
- this.updateWhenAtViewer()
- e.changeInfo.projectionChanged && this.setViewLimit()
- }
- needUpdateCursor && this.updateCursor()
- })
- this.addEventListener("camera_changed", (e)=>{
- e.changeInfo.projectionChanged && this.setViewLimit()
- })
-
- //viewer.addEventListener("global_mousemove", this.updateWhenAtViewer.bind(this)) //鼠标移动时reticule也动,所以直接就needRender
- /* viewer.reticule.addEventListener('update',(e)=>{
- if(this.attachedToViewer)this.needRender = true
- }) */
-
-
- viewer.scene.addEventListener("360_images_added", this.addPanos.bind(this))
-
-
- viewer.addEventListener("loadPointCloudDone", this.initProjection.bind(this))
-
- this.addEventListener('global_click',(e)=>{
- if(!e.isTouch && e.button != THREE.MOUSE.LEFT)return
- this.updateClosestPano(e.intersect)
- })
-
-
-
- this.addEventListener('add',(e)=>{//添加其他mesh
- this.scene.add(e.object)
- if(e.name == 'route'){
- e.object.position.z = routeLayerHeight
- }
- Potree.Utils.setObjectLayers(e.object, 'mapObjects' )
- })
-
-
- viewer.addEventListener('allLoaded',()=>{
-
- this.setViewLimit('standard')
-
- })
-
-
- if(!Potree.settings.isOfficial){
- let domRoot = viewer.renderer.domElement.parentElement;
- let elAttach = $("<input type='button' value='map绑定'></input>");
- elAttach.css({
- position : "absolute",
- right : '80%',
- bottom: '20px',
- zIndex: "10000",
- fontSize:'1em', color:"black",
- background:'rgba(255,255,255,0.8)',
- })
- let state = false
- elAttach.on("click", () => {
- state = !state
- this.attachToMainViewer(state, 'measure')
- elAttach.val(state ? 'map分离':'map绑定')
- });
- domRoot.appendChild(elAttach[0]);
-
-
- }
-
- }
-
-
- get needRender(){
- return this.needRender_
- }
- set needRender(n){
- this.needRender_ = n
- n && (this.viewports[0].needRender = true) //使attachedToViewer时在renderDefault中可渲染
- }
- get mapChanged(){
- return this.mapChanged_
- }
- set mapChanged(c){//镜头移动、地图内容改变都会为true
- this.mapChanged_ = c
- c && (this.needRender = true)
- }
-
-
-
- waitLoadDone(callback){//确保加载完后执行
- let timer //等待一段时间看有没有新加载的tile,如果超过这个时间没有就不等了,算加载结束
-
- let pauseCountDown = ()=>{//重新等待加载结束,中断倒计时
- clearTimeout(timer)
- //console.log('pauseCountDown')
- }
-
- let freshCountDown = ()=>{//刷新倒计时
- //console.log('freshCountDown')
-
- clearTimeout(timer)
- timer = setTimeout(()=>{
- this.mapLayer.removeEventListener('loadDone', freshCountDown)
- this.mapLayer.removeEventListener('startLoad', pauseCountDown)
- callback()
- }, document.hidden ? 5000 : 500)
- }
-
-
- this.mapLayer.addEventListener('loadDone', freshCountDown)
- this.mapLayer.addEventListener('startLoad', pauseCountDown)
- if(this.mapLayer.loadingInProgress == 0){
- freshCountDown()
- }
- }
-
-
-
-
-
-
- addListener(images360){
- images360.addEventListener('flyToPano',e=>{
- let toPano = e.toPano
- if(toPano.dontMoveMap) return
-
- /* transitions.start(lerp.vector(this.view.position, toPano.pano.position.clone().setZ(cameraHeight),
-
- (pos, progress)=>{
-
- }), toPano.duration, null, 0, easing[toPano.easeName] ); */
- let boundSize// = new THREE.Vector2(10,10)
-
- this.moveTo(toPano.pano.position.clone().setZ(Potree.config.map.cameraHeight), boundSize, toPano.duration, null, toPano.easeName)
- })
-
-
- }
-
-
-
- initProjection(){
- this.started = true
- this.mapLayer.initProjection()
-
- }
-
- initScene(){
- let w = initCameraFeildWidth
- let width = this.renderArea.clientWidth;
- let height = this.renderArea.clientHeight;
- //let aspect = width / height
- this.camera = new THREE.OrthographicCamera(-width/2,width/2,height/2,-height/2/* -w/2, w/2, w/2/aspect, -w/2/aspect */, 0.01, 10000);
- this.camera.zoom = width / w //zoom越大视野越小
- //this.camera.position.set(0,0,10);
- this.camera.up.set(0,0,1)
- //this.camera.lookAt(new THREE.Vector3())
- //this.camera.updateMatrixWorld()
-
- this.view = new ExtendView();
- this.view.position.set(0,0,Potree.config.map.cameraHeight);
- this.view.lookAt(0,0,0)
-
-
- let viewport = new Viewport( this.view, this.camera, {
- left:0, bottom:0, width:1, height: 1, name:'mapViewport'
- })
- viewport.axis = ["x","y"]
- viewport.axisSign = [1,1]
-
- viewport.noPointcloud = true; //不要渲染点云
- viewport.render = this.render.bind(this)//标志给mainView渲染
- //viewport.unableDepth = true //depthBasicMaterial等在此viewport中不开启depth
-
-
- viewport.addEventListener('resize',()=>{
- this.copyBuffer.setSize(viewport.resolution2.x, viewport.resolution2.y)
- })
- this.viewports = [viewport]
-
-
-
-
- this.controls = new FirstPersonControls(this, this.viewports[0]);
- this.controls.setEnable(true)
- this.scene = new THREE.Scene();
-
-
-
- this.inputHandler = new InputHandler(this, this.scene);
- this.inputHandler.name = 'mapInputHandler'
- //this.inputHandler.addInputListener(this.controls);
- this.inputHandler.registerInteractiveScene(this.scene);//interactiveScenes
-
- this.viewports[0].interactiveScenes = this.inputHandler.interactiveScenes;//供viewer的inputHandler使用
-
- var cursor = new THREE.Mesh(planeGeo, new THREE.MeshBasicMaterial({
- transparent:true,
- opacity:0.9,
- depthTest : false, //防止透明冲突
- map: texLoader.load(Potree.resourcePath+'/textures/pic_location128.png' )
- }))
- cursor.position.set(0,0,cursorHeight);
-
-
- this.cursor = cursor
-
- this.scene.add(cursor)
- Potree.Utils.setObjectLayers(this.scene, 'mapObjects' )
- }
-
- setViewLimit(state){//设置边界,当编辑空间模型等时要解禁
- if(!state)state = this.limitBoundState
- if(!state)return
- this.limitBoundState = state
-
- let setting = Potree.config.OrthoCameraLimit[state]
- if(setting){
- this.camera.zoomLimit = $.extend({},setting.zoom);
-
-
- let lonlatCenter = viewer.transform.lonlatToLocal.inverse([0,0]);
- let minY = viewer.transform.lonlatToLocal.forward([lonlatCenter[0], -90+setting.latPad])[1] //屏幕边界的bound
- let maxY = viewer.transform.lonlatToLocal.forward([lonlatCenter[0], 90-setting.latPad])[1]
- /*this.view.limitBound = new THREE.Box3(
- new THREE.Vector3(setting.xBound[0], minY, Potree.config.map.cameraHeight),
- new THREE.Vector3(setting.xBound[1], maxY, 1 / 0)
- ) */
-
- let halfHeight = this.viewports[0].resolution.y / 2 / this.camera.zoom;//屏幕所占高度的一半
- let halfWidth = this.viewports[0].resolution.x / 2 / this.camera.zoom;
- this.view.limitBound = new THREE.Box3(
- new THREE.Vector3(setting.xBound[0]+halfWidth, minY+halfHeight, Potree.config.map.cameraHeight),
- new THREE.Vector3(setting.xBound[1]-halfWidth, maxY-halfHeight, 1 / 0)
- )
-
-
- }else{
- this.view.limitBound = null
- this.camera.zoomLimit = null
- }
-
- }
-
- updateCursor(){
- //console.log('pos', viewer.mainViewport.camera.position.toArray() )
- var scale = math.getScaleForConstantSize( {//规定下最小最大像素
- minSize : 80, maxSize : 200, nearBound : initCameraFeildWidth*0.1 , farBound : initCameraFeildWidth*2,
- camera:this.camera , position: this.cursor.getWorldPosition(new THREE.Vector3()),
- resolution: this.viewports[0].resolution//2
- })
- this.cursor.scale.set(scale, scale, scale);//当地图缩放时
- this.cursor.position.copy(viewer.mainViewport.camera.position).setZ(cursorHeight)//当场景镜头旋转移动时
- this.cursor.rotation.z = viewer.mainViewport.view.yaw
- this.needRender = true
- }
-
- addPanos(e){
- var panosGroup = new THREE.Object3D; panosGroup.name = 'markers'
- panoMarkerMats = {
- default: new THREE.MeshBasicMaterial({
- transparent:true,
- opacity: 0.5,
- map: texLoader.load(Potree.resourcePath+'/textures/map_marker.png' ),
- }),
- selected: new THREE.MeshBasicMaterial({
- transparent:true,
- opacity: 1,
- map: texLoader.load(Potree.resourcePath+'/textures/map_marker.png' ),
- })
- }
-
-
- e.images.panos.forEach(pano=>{
- pano.mapMarker = new THREE.Mesh(planeGeo, panoMarkerMats.default);
- pano.mapMarker.position.copy(pano.position).setZ(0)
- pano.mapMarker.scale.set(markerSize,markerSize,markerSize)
- pano.mapMarker.name = 'mapMarker'
- panosGroup.add(pano.mapMarker);
-
-
- let mouseover = (e)=>{
- if(!e.byMap){
- pano.mapMarker.material = panoMarkerMats.selected
- if(!e.byMainView) pano.dispatchEvent({type: "hoverOn", byMap:true})
- this.needRender = true
- }
- }
-
- let mouseleave = (e)=>{
- if(!e.byMap){
- pano.mapMarker.material = panoMarkerMats.default
- if(!e.byMainView) pano.dispatchEvent({type: "hoverOff", byMap:true})
- this.needRender = true
- }
- }
-
-
- pano.mapMarker.addEventListener('mouseover', mouseover);
- pano.mapMarker.addEventListener('mouseleave', mouseleave);
-
- pano.addEventListener('hoverOn', mouseover)
- pano.addEventListener('hoverOff', mouseleave)
-
- let onclick = (e)=>{
- viewer.images360.flyToPano(pano)
- }
- pano.mapMarker.addEventListener('click', onclick);
-
- pano.addEventListener('isVisible',(e)=>{//是否显示该点的mesh(不显示也能走)
- //console.log('panoMarker isVisible', pano.id, e.visible)
- Potree.Utils.updateVisible(pano.mapMarker, 'panoVisible', e.visible )
- this.needRender = true
-
- })
- pano.addEventListener('rePos',(e)=>{
- pano.mapMarker.position.copy(pano.position).setZ(0)
- })
- })
- this.scene.add(panosGroup)
- panosGroup.position.z = panosHeight
- this.panosGroup = panosGroup
- Potree.Utils.setObjectLayers(panosGroup, 'mapObjects' )
-
-
- /* e.images.on('markersDisplayChange', (show)=>{
- panosGroup.visible = show
- this.needRender = true
- }) */
-
- //-------
-
- //this.fitPanosToViewport()
- this.initFitView()
- }
-
-
-
- updateClosestPano(intersect){
- if(viewer.images360.flying)return;
- intersect = intersect && intersect.orthoIntersect
- if(!intersect)return
-
- intersect = intersect.clone().setZ(0)
-
- const minDis = 20 //距离鼠标不能太远
-
- var filterFuncs = [
- Images360.filters.isEnabled(),
- Images360.filters.isVisible(),//只走显示的点,否则会走到别的层
- (pano)=>{
- return pano.position.clone().setZ(0).distanceTo(intersect) < minDis
- },
- ];
-
- var pano = Common.find(viewer.images360.panos, filterFuncs, [Images360.sortFunctions.floorDisSquaredToPoint(intersect)]);
- if (pano && pano != viewer.images360.currentPano ) {
- viewer.images360.flyToPano(pano)
-
- }
-
- }
-
-
- fitPanosToViewport(){//使所有漫游点占满viewport
-
- //var w = viewer.bound.boundSize.x;
- var boundSize = viewer.images360.bound.size.clone().multiplyScalar(1.1);
- boundSize.max(new THREE.Vector3(4,4,4))
- let endPosition = viewer.images360.bound.center.clone()
- this.moveTo(endPosition, boundSize, 0)
- }
- fitToPointcloud(pointcloud, duration=400){
- var boundSize = pointcloud.bound.getSize(new THREE.Vector3)/* .multiplyScalar(1.1); */
- boundSize.max(new THREE.Vector3(4,4,4))
- let endPosition = pointcloud.bound.getCenter(new THREE.Vector3)
- this.moveTo(endPosition, boundSize, duration) //给点duration去变化 否则地图放大后所占的还是很小
- }
- initFitView(){
- let dis = 5 , px = 70 //地图上px像素长度代表的距离为dis //px是手动缩放到5m后发现是这个长度
- let zoom = px / dis;
- this.camera.zoom = zoom
- this.moveTo(viewer.images360.position/* viewer.images360.bound.center */)
- this.camera.updateProjectionMatrix()
- }
-
- fitToDatasets(datasets){
- let bound = new THREE.Box3;
- datasets.forEach(e=>bound.union(e.bound))
- let center = bound.getCenter(new THREE.Vector3)
- let size = bound.getSize(new THREE.Vector3)
-
- this.moveTo(center, size, 200 ) //给duration是为了顺应视口大小改变,缓冲
- }
-
- moveTo(endPosition, boundSize, duration=0, margin, easeName, callback ){//前两个参数有xy即可
- endPosition = new THREE.Vector3(endPosition.x,endPosition.y,Potree.config.map.cameraHeight)
- this.view.moveOrthoCamera(this.viewports[0], {endPosition, boundSize, margin, callback}, duration, easeName)
-
-
-
-
- /* let endZoom, startZoom = this.camera.zoom
-
- //修改相机为bound中心,这样能看到全部(宽度范围内)
-
- this.view.setView({ position:endPosition, duration,
- callback:()=>{//done
-
- },
- onUpdate:(progress)=>{
- if(boundSize){
- let aspect = boundSize.x / boundSize.y
- let w, h;
-
- if(this.camera.aspect > aspect){//视野更宽则用bound的纵向来决定
- h = boundSize.y
- //w = h * this.camera.aspect
- endZoom = this.viewports[0].resolution.y / h
- }else{
- w = boundSize.x;
- //h = w / this.camera.aspect
- endZoom = this.viewports[0].resolution.x / w
- }
- //onUpdate时更新endzoom是因为画布大小可能更改
-
-
- this.camera.zoom = endZoom * progress + startZoom * (1 - progress)
- this.camera.updateProjectionMatrix()
- }
- },
-
- Easing:easeName
-
- }) */
-
-
- }
-
-
-
-
- updateWhenAtViewer(e){//两个触发来源: 1 camera_changed时 2 mapLayer.needUpdate时。 render在viewer中执行
- if(this.attachedToViewer){
- if(this.started) this.mapLayer.update()
- this.needRender = true
- }
- }
-
- update(delta, areaSize ){
- if(!this.visible && !this.attachedToViewer )return
-
-
- if(this.attachedToViewer){
- if(this.mapLayer.needUpdate){
- this.updateWhenAtViewer()
- }
- return
- }
-
-
- this.updateScreenSize()
-
- this.controls.update(delta);
- this.view.applyToCamera(this.camera)
-
-
- let changed = this.cameraChanged()
-
-
- if(this.started && (changed || this.mapLayer.needUpdate))this.mapLayer.update()
-
- if(changed /*|| || this.needRender */){
- /* this.dispatchEvent({
- type: "camera_changed",
- camera: this.camera,
- viewport : this.viewports[0]
- }) */
- this.mapChanged = true
- this.needRender = true
- this.updateCursor()//更改大小
-
- }
- this.render()
-
- }
-
- attachToMainViewer(state, desc, mapRatio=0.5, options={}){//转移到viewer中。测量时展示or截图需要
-
- if(!Potree.settings.isOfficial)this.renderArea.style.display = state ? 'none':'block'
-
- if(state){
- this.enabledOld = this.enabled
- this.enabled = true
-
- if(mapRatio != 'dontSet'){
- this.changeSplitScreenDir(options.dir, mapRatio)
-
- if(this.attachedToViewer){
- //this.fitPanosToViewport()
- viewer.updateScreenSize({forceUpdateSize:true})
- return
- }
- viewer.viewports = [viewer.mainViewport, viewer.mapViewer.viewports[0] ];//因为mainViewer的相机变化会触发map的变化,所以先渲染mainViewer
- }
-
-
- if(desc == 'measure') this.inputHandler.registerInteractiveScene(viewer.measuringTool.scene);//虽然用的是viewer的inputHandler,但借用了this.inputHandler的interactiveScenes
- else if(desc == 'split4Screens') {
- this.inputHandler.registerInteractiveScene(viewer.scene.scene);
- }
-
- }else{
- if(!this.attachedToViewer)return
-
- viewer.mainViewport.left = 0;
- viewer.mainViewport.bottom = 0;
- viewer.mainViewport.width = 1;
- viewer.mainViewport.height = 1;
-
- this.viewports[0].width = 1;
- this.viewports[0].bottom = 0;
- this.viewports[0].height = 1;
- this.viewports[0].left = 0;
-
- this.renderMeasure || this.inputHandler.unregisterInteractiveScene(viewer.measuringTool.scene);
- this.inputHandler.unregisterInteractiveScene(viewer.scene.scene);
- viewer.viewports = [viewer.mainViewport]
- this.updateScreenSize({forceUpdateSize:true}) //更新相机projectionMatrix
- }
-
- //if(desc == 'measure')this.renderMeasure = state
- this.attachedToViewer = state
-
-
-
-
-
- viewer.updateScreenSize({forceUpdateSize:true})
-
-
- //mapRatio != 'dontSet' && !options.dontFit && this.moveTo(...)//要写在updateScreenSize后面,因为要根据视图大小来fit
- if(options.moveToCurrentPos){
- let boundSize = new THREE.Vector2(10,10)
- let duration = 1000
- this.moveTo(viewer.images360.position.clone(), boundSize, duration)
- }
- this.needRender = true
- }
-
-
- setDrawMeasure(draw){
- this.renderMeasure = !!draw
- if(draw){
- this.inputHandler.registerInteractiveScene(viewer.measuringTool.scene);
- }else{
- this.inputHandler.unregisterInteractiveScene(viewer.measuringTool.scene);
- }
- }
-
- changeSplitScreenDir(dir, mapRatio){//左右 | 上下
- //if(!dir || dir == this.dir)return
- if(dir )this.splitDir = dir
- this.updateSplitSize(mapRatio)
- /* if(this.attachedToViewer){ //如果已经分屏了,中途修改方向的话……
- this.updateSplitSize()
- } */
- }
- updateSplitSize(mapRatio){
- if(mapRatio != void 0) this.mapRatio = mapRatio
-
- //console.log(this.mapRatio)
-
- if(this.splitDir == 'leftRight'){//地图在左方
- viewer.mainViewport.left = this.mapRatio
- viewer.mainViewport.width = 1-this.mapRatio
- this.viewports[0].width = this.mapRatio;
-
- viewer.mainViewport.bottom = this.viewports[0].bottom = 0
- viewer.mainViewport.height = this.viewports[0].height = 1
-
- }else if(this.splitDir == 'upDown'){ //地图在下方
- viewer.mainViewport.bottom = this.mapRatio
- viewer.mainViewport.height = 1-this.mapRatio
- this.viewports[0].height = this.mapRatio;
-
- viewer.mainViewport.left = this.viewports[0].left = 0
- viewer.mainViewport.width = this.viewports[0].width = 1
-
- }
- if(this.attachedToViewer){
- viewer.updateScreenSize({forceUpdateSize:true})
- }
- }
-
- render1(params={}){//viewer的preserveDrawingBuffer为false时的版本
- let needCopy, waitCopy
- if(!this.visible && !this.attachedToViewer || !this.needRender && !params.force){
- if(this.attachedToViewer ){
- needCopy = true
- }else{
- return
- }
- }
- waitCopy = this.attachedToViewer && this.needRender && !params.force//是否写入到copyBuffer。双屏时,若needRender就拷贝到copyBuffer中,双屏时就直接使用copyBuffer。 四屏时因渲染点云会每帧都渲染,所以不需要缓存。
-
- let renderer = params.renderer || this.renderer
-
- if(waitCopy){
- this.copyBuffer.setSize(params.viewport.resolution2.x, params.viewport.resolution2.y)
- renderer.setRenderTarget(this.copyBuffer)
- }else if(params.target){
- renderer.setRenderTarget(params.target)
- }
- /* if(params.resize){
- this.emitResizeMsg(new THREE.Vector2(params.width,params.height, viewport:params.viewport))
- } */
- params.clear ? params.clear() : renderer.clear();
-
- if(!needCopy || waitCopy){//重绘
- viewer.dispatchEvent({type: "render.begin", viewer: this, viewport:this.viewports[0], params });
- Potree.Utils.setCameraLayers(this.camera, ['map','mapObjects' , 'bothMapAndScene' ])
-
- if(this.mapGradientBG){//渲染背景
- viewer.scene.cameraBG.layers.set(Potree.config.renderLayers.bg);
- renderer.render(viewer.scene.scene, viewer.scene.cameraBG);
- }
-
- renderer.render(this.scene, this.camera);
- renderer.render(viewer.scene.scene, this.camera);
-
- //测量线等
- //params.renderOverlay && params.renderOverlay( $.extend({}, params, { isMap:true }))
-
- renderer.setRenderTarget(params.target||null)
- }
-
- if(needCopy || waitCopy){//使用缓存 ----当viewer的preserveDrawingBuffer为false的话,使用buffer
- this.copyPass.render(null,null, null, renderer, params.target||null, this.copyBuffer)
- }
- this.needRender = false
- return true
- }
-
- clear(params){
- if(this.transparentBG){
- this.renderer.setClearColor( 0x000000, 0 );
- }else{
- this.renderer.setClearColor( Potree.config.mapBG, 1 );
- }
-
- (params.renderer || this.renderer).clear()
- }
-
-
- //拆成两次渲染,一个地图一个其他物体,且地图渲染后保存在buffer中,只有当地图变化后才重渲染。
- render(params={}){
-
- if(!this.visible && !this.attachedToViewer || !this.needRender && !params.force){ //注意:mapViewer.needRender的权重高于它的viewport的needRender,也就是说,当attachedToViewer时,viewer即使needRender, mapViewer也不一定会渲染。
- return
- }
- viewer.addTimeMark('mapRender','start')
- let renderer = params.renderer || this.renderer
-
- if(this.mapChanged){ //渲染地图背景
- renderer.setRenderTarget(this.copyBuffer)
- params.clear ? params.clear(params) : this.clear(params);
-
-
- if(this.mapGradientBG){//渲染背景
- viewer.scene.cameraBG.layers.set(Potree.config.renderLayers.bg);
- renderer.render(viewer.scene.scene, viewer.scene.cameraBG);
- }
- Potree.Utils.setCameraLayers(this.camera, ['map'])
- renderer.render(this.scene, this.camera);
-
- params.renderBG && params.renderBG(this.viewports[0])
-
- this.mapChanged = false
- renderer.setRenderTarget(params.target||null)
- }
-
- params.clear ? params.clear(params) : this.clear(params);
- this.copyPass.render(null,null, null,renderer, params.target||null, this.copyBuffer) //拷贝地图背景
- renderer.clearDepth(); //防止地图遮挡其他物体
-
-
-
- //绘制其他物体
- Potree.Utils.setCameraLayers(this.camera, ['mapObjects' , 'bothMapAndScene' ])
- viewer.dispatchEvent({type: "render.begin", viewer: this, viewport:this.viewports[0], params });
-
- this.attachedToViewer || renderer.render(viewer.scene.scene, this.camera); //类同renderOverlay
- renderer.render(this.scene, this.camera);
- if(!this.attachedToViewer && this.renderMeasure){//在未attach到主页面时也要渲染测量线
- viewer.dispatchEvent({type: "render.pass.perspective_overlay", camera:this.camera, /* screenshot:params.screenshot, */viewport:this.viewports[0], renderer});
- }
-
-
- renderer.setRenderTarget(null)
-
- this.needRender = false
-
- viewer.addTimeMark('mapRender','end')
-
- return true
- }
- renderOverlay(){//偶尔需要绘制测量线
- viewer.renderOverlay({
- camera: this.camera, viewport:this.viewports[0], renderer:this.renderer
- })
- }
-
-
-
-
- }
- /*
- 渲染顺序:
- 地图
- 背景Overlay
- 地图scene的物体,如cursor、 marker
- 点云(如果有)
- overlay,两层:第一层:viewer的scene中bothMapAndScene的如reticule. 第二层:如测量线(attachToMainViewer时才渲染)
-
-
- */
- //本地调试地图白屏是因为代码自动更新了 但没刷新
|