MapViewer.js 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780
  1. import * as THREE from "../../../../libs/three.js/build/three.module.js";
  2. import {MapLayer} from './Map.js'
  3. import {FirstPersonControls} from '../../../navigation/FirstPersonControlsNew.js'
  4. import {InputHandler} from "../../../navigation/InputHandlerNew.js";
  5. import {ViewerBase} from "../viewerBase.js"
  6. import {ExtendView} from "../../../viewer/ExtendView.js";
  7. import Viewport from "../Viewport.js";
  8. import math from "../../utils/math.js";
  9. //import CursorDeal from '../utils/CursorDeal.js'
  10. import {Images360} from '../../modules/panos/Images360.js'
  11. import Common from '../../utils/Common.js'
  12. import {transitions, easing, lerp} from "../../utils/transitions.js";
  13. import {config } from "../../settings.js";
  14. /* var centerCross = new THREE.Mesh(new THREE.SphereGeometry(1, 4, 4),new THREE.MeshBasicMaterial({
  15. transparent:true, color:"#ff0000", opacity:0.5
  16. })); */
  17. import CopyShader from '../../materials/postprocessing/CopyShader.js'
  18. import {ShaderPass} from '../../materials/postprocessing/ShaderPass.js'
  19. /* const mapHeight = -1000;//要比点云低。最低
  20. const cameraHeight = 1000; //最高 */
  21. const panosHeight = config.map.mapHeight + 100 //要比点云低 (marker)
  22. const cursorHeight = 0;//比地图高就行
  23. const routeLayerHeight = config.map.mapHeight + 105
  24. const texLoader = new THREE.TextureLoader()
  25. const planeGeo = new THREE.PlaneBufferGeometry(1,1)
  26. const markerSize = 1;
  27. var initCameraFeildWidth = 50
  28. var panoMarkerMats
  29. export class MapViewer extends ViewerBase{
  30. constructor(dom){
  31. super(dom, {
  32. clearColor: Potree.config.mapBG,
  33. name: 'mapViewer'
  34. })
  35. this.visible = true
  36. this.initScene()
  37. this.needRender_ = false
  38. this.mapLayer = new MapLayer(this, this.viewports[0])
  39. this.scene.add(this.mapLayer.sceneGroup)
  40. this.mapLayer.sceneGroup.position.setZ(Potree.config.map.mapHeight)
  41. this.mapRatio = 0.5
  42. this.splitDir = 'leftRight'
  43. //因context的preserveDrawingBuffer为false之后,canvas渲染多个viewport时会自动clear,所以若不渲染就会是空的。所以没有变化时就直接拷贝buffer好了。
  44. this.copyPass = new ShaderPass( CopyShader );
  45. this.copyBuffer = new THREE.WebGLRenderTarget( 100, 100 , {
  46. minFilter: THREE.LinearFilter,
  47. magFilter: THREE.LinearFilter,
  48. format: THREE.RGBAFormat,
  49. stencilBuffer: false,
  50. });
  51. viewer.addEventListener("camera_changed", (e)=>{
  52. let needUpdateCursor
  53. if(e.viewport == viewer.mainViewport){
  54. needUpdateCursor = true
  55. }else if(e.viewport == this.viewports[0]){//attachedToViewer
  56. needUpdateCursor = true
  57. this.mapChanged = true
  58. this.updateWhenAtViewer()
  59. e.changeInfo.projectionChanged && this.setViewLimit()
  60. }
  61. needUpdateCursor && this.updateCursor()
  62. })
  63. this.addEventListener("camera_changed", (e)=>{
  64. e.changeInfo.projectionChanged && this.setViewLimit()
  65. })
  66. //viewer.addEventListener("global_mousemove", this.updateWhenAtViewer.bind(this)) //鼠标移动时reticule也动,所以直接就needRender
  67. /* viewer.reticule.addEventListener('update',(e)=>{
  68. if(this.attachedToViewer)this.needRender = true
  69. }) */
  70. viewer.scene.addEventListener("360_images_added", this.addPanos.bind(this))
  71. viewer.addEventListener("loadPointCloudDone", this.initProjection.bind(this))
  72. this.addEventListener('global_click',(e)=>{
  73. if(!e.isTouch && e.button != THREE.MOUSE.LEFT)return
  74. this.updateClosestPano(e.intersect)
  75. })
  76. this.addEventListener('add',(e)=>{//添加其他mesh
  77. this.scene.add(e.object)
  78. if(e.name == 'route'){
  79. e.object.position.z = routeLayerHeight
  80. }
  81. Potree.Utils.setObjectLayers(e.object, 'mapObjects' )
  82. })
  83. viewer.addEventListener('allLoaded',()=>{
  84. this.setViewLimit('standard')
  85. })
  86. if(!Potree.settings.isOfficial){
  87. let domRoot = viewer.renderer.domElement.parentElement;
  88. let elAttach = $("<input type='button' value='map绑定'></input>");
  89. elAttach.css({
  90. position : "absolute",
  91. right : '80%',
  92. bottom: '20px',
  93. zIndex: "10000",
  94. fontSize:'1em', color:"black",
  95. background:'rgba(255,255,255,0.8)',
  96. })
  97. let state = false
  98. elAttach.on("click", () => {
  99. state = !state
  100. this.attachToMainViewer(state, 'measure')
  101. elAttach.val(state ? 'map分离':'map绑定')
  102. });
  103. domRoot.appendChild(elAttach[0]);
  104. }
  105. }
  106. get needRender(){
  107. return this.needRender_
  108. }
  109. set needRender(n){
  110. this.needRender_ = n
  111. n && (this.viewports[0].needRender = true) //使attachedToViewer时在renderDefault中可渲染
  112. }
  113. get mapChanged(){
  114. return this.mapChanged_
  115. }
  116. set mapChanged(c){//镜头移动、地图内容改变都会为true
  117. this.mapChanged_ = c
  118. c && (this.needRender = true)
  119. }
  120. waitLoadDone(callback){//确保加载完后执行
  121. let timer //等待一段时间看有没有新加载的tile,如果超过这个时间没有就不等了,算加载结束
  122. let pauseCountDown = ()=>{//重新等待加载结束,中断倒计时
  123. clearTimeout(timer)
  124. //console.log('pauseCountDown')
  125. }
  126. let freshCountDown = ()=>{//刷新倒计时
  127. //console.log('freshCountDown')
  128. clearTimeout(timer)
  129. timer = setTimeout(()=>{
  130. this.mapLayer.removeEventListener('loadDone', freshCountDown)
  131. this.mapLayer.removeEventListener('startLoad', pauseCountDown)
  132. callback()
  133. }, document.hidden ? 5000 : 500)
  134. }
  135. this.mapLayer.addEventListener('loadDone', freshCountDown)
  136. this.mapLayer.addEventListener('startLoad', pauseCountDown)
  137. if(this.mapLayer.loadingInProgress == 0){
  138. freshCountDown()
  139. }
  140. }
  141. addListener(images360){
  142. images360.addEventListener('flyToPano',e=>{
  143. let toPano = e.toPano
  144. if(toPano.dontMoveMap) return
  145. /* transitions.start(lerp.vector(this.view.position, toPano.pano.position.clone().setZ(cameraHeight),
  146. (pos, progress)=>{
  147. }), toPano.duration, null, 0, easing[toPano.easeName] ); */
  148. let boundSize// = new THREE.Vector2(10,10)
  149. this.moveTo(toPano.pano.position.clone().setZ(Potree.config.map.cameraHeight), boundSize, toPano.duration, null, toPano.easeName)
  150. })
  151. }
  152. initProjection(){
  153. this.started = true
  154. this.mapLayer.initProjection()
  155. }
  156. initScene(){
  157. let w = initCameraFeildWidth
  158. let width = this.renderArea.clientWidth;
  159. let height = this.renderArea.clientHeight;
  160. //let aspect = width / height
  161. 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);
  162. this.camera.zoom = width / w //zoom越大视野越小
  163. //this.camera.position.set(0,0,10);
  164. this.camera.up.set(0,0,1)
  165. //this.camera.lookAt(new THREE.Vector3())
  166. //this.camera.updateMatrixWorld()
  167. this.view = new ExtendView();
  168. this.view.position.set(0,0,Potree.config.map.cameraHeight);
  169. this.view.lookAt(0,0,0)
  170. let viewport = new Viewport( this.view, this.camera, {
  171. left:0, bottom:0, width:1, height: 1, name:'mapViewport'
  172. })
  173. viewport.axis = ["x","y"]
  174. viewport.axisSign = [1,1]
  175. viewport.noPointcloud = true; //不要渲染点云
  176. viewport.render = this.render.bind(this)//标志给mainView渲染
  177. //viewport.unableDepth = true //depthBasicMaterial等在此viewport中不开启depth
  178. viewport.addEventListener('resize',()=>{
  179. this.copyBuffer.setSize(viewport.resolution2.x, viewport.resolution2.y)
  180. })
  181. this.viewports = [viewport]
  182. this.controls = new FirstPersonControls(this, this.viewports[0]);
  183. this.controls.setEnable(true)
  184. this.scene = new THREE.Scene();
  185. this.inputHandler = new InputHandler(this, this.scene);
  186. this.inputHandler.name = 'mapInputHandler'
  187. //this.inputHandler.addInputListener(this.controls);
  188. this.inputHandler.registerInteractiveScene(this.scene);//interactiveScenes
  189. this.viewports[0].interactiveScenes = this.inputHandler.interactiveScenes;//供viewer的inputHandler使用
  190. var cursor = new THREE.Mesh(planeGeo, new THREE.MeshBasicMaterial({
  191. transparent:true,
  192. opacity:0.9,
  193. depthTest : false, //防止透明冲突
  194. map: texLoader.load(Potree.resourcePath+'/textures/pic_location128.png' )
  195. }))
  196. cursor.position.set(0,0,cursorHeight);
  197. this.cursor = cursor
  198. this.scene.add(cursor)
  199. Potree.Utils.setObjectLayers(this.scene, 'mapObjects' )
  200. }
  201. setViewLimit(state){//设置边界,当编辑空间模型等时要解禁
  202. if(!state)state = this.limitBoundState
  203. if(!state)return
  204. this.limitBoundState = state
  205. let setting = Potree.config.OrthoCameraLimit[state]
  206. if(setting){
  207. this.camera.zoomLimit = $.extend({},setting.zoom);
  208. let lonlatCenter = viewer.transform.lonlatToLocal.inverse([0,0]);
  209. let minY = viewer.transform.lonlatToLocal.forward([lonlatCenter[0], -90+setting.latPad])[1] //屏幕边界的bound
  210. let maxY = viewer.transform.lonlatToLocal.forward([lonlatCenter[0], 90-setting.latPad])[1]
  211. /*this.view.limitBound = new THREE.Box3(
  212. new THREE.Vector3(setting.xBound[0], minY, Potree.config.map.cameraHeight),
  213. new THREE.Vector3(setting.xBound[1], maxY, 1 / 0)
  214. ) */
  215. let halfHeight = this.viewports[0].resolution.y / 2 / this.camera.zoom;//屏幕所占高度的一半
  216. let halfWidth = this.viewports[0].resolution.x / 2 / this.camera.zoom;
  217. this.view.limitBound = new THREE.Box3(
  218. new THREE.Vector3(setting.xBound[0]+halfWidth, minY+halfHeight, Potree.config.map.cameraHeight),
  219. new THREE.Vector3(setting.xBound[1]-halfWidth, maxY-halfHeight, 1 / 0)
  220. )
  221. }else{
  222. this.view.limitBound = null
  223. this.camera.zoomLimit = null
  224. }
  225. }
  226. updateCursor(){
  227. //console.log('pos', viewer.mainViewport.camera.position.toArray() )
  228. var scale = math.getScaleForConstantSize( {//规定下最小最大像素
  229. minSize : 80, maxSize : 200, nearBound : initCameraFeildWidth*0.1 , farBound : initCameraFeildWidth*2,
  230. camera:this.camera , position: this.cursor.getWorldPosition(new THREE.Vector3()),
  231. resolution: this.viewports[0].resolution//2
  232. })
  233. this.cursor.scale.set(scale, scale, scale);//当地图缩放时
  234. this.cursor.position.copy(viewer.mainViewport.camera.position).setZ(cursorHeight)//当场景镜头旋转移动时
  235. this.cursor.rotation.z = viewer.mainViewport.view.yaw
  236. this.needRender = true
  237. }
  238. addPanos(e){
  239. var panosGroup = new THREE.Object3D; panosGroup.name = 'markers'
  240. panoMarkerMats = {
  241. default: new THREE.MeshBasicMaterial({
  242. transparent:true,
  243. opacity: 0.5,
  244. map: texLoader.load(Potree.resourcePath+'/textures/map_marker.png' ),
  245. }),
  246. selected: new THREE.MeshBasicMaterial({
  247. transparent:true,
  248. opacity: 1,
  249. map: texLoader.load(Potree.resourcePath+'/textures/map_marker.png' ),
  250. })
  251. }
  252. e.images.panos.forEach(pano=>{
  253. pano.mapMarker = new THREE.Mesh(planeGeo, panoMarkerMats.default);
  254. pano.mapMarker.position.copy(pano.position).setZ(0)
  255. pano.mapMarker.scale.set(markerSize,markerSize,markerSize)
  256. pano.mapMarker.name = 'mapMarker'
  257. panosGroup.add(pano.mapMarker);
  258. let mouseover = (e)=>{
  259. if(!e.byMap){
  260. pano.mapMarker.material = panoMarkerMats.selected
  261. if(!e.byMainView) pano.dispatchEvent({type: "hoverOn", byMap:true})
  262. this.needRender = true
  263. }
  264. }
  265. let mouseleave = (e)=>{
  266. if(!e.byMap){
  267. pano.mapMarker.material = panoMarkerMats.default
  268. if(!e.byMainView) pano.dispatchEvent({type: "hoverOff", byMap:true})
  269. this.needRender = true
  270. }
  271. }
  272. pano.mapMarker.addEventListener('mouseover', mouseover);
  273. pano.mapMarker.addEventListener('mouseleave', mouseleave);
  274. pano.addEventListener('hoverOn', mouseover)
  275. pano.addEventListener('hoverOff', mouseleave)
  276. let onclick = (e)=>{
  277. viewer.images360.flyToPano(pano)
  278. }
  279. pano.mapMarker.addEventListener('click', onclick);
  280. pano.addEventListener('isVisible',(e)=>{//是否显示该点的mesh(不显示也能走)
  281. //console.log('panoMarker isVisible', pano.id, e.visible)
  282. Potree.Utils.updateVisible(pano.mapMarker, 'panoVisible', e.visible )
  283. this.needRender = true
  284. })
  285. pano.addEventListener('rePos',(e)=>{
  286. pano.mapMarker.position.copy(pano.position).setZ(0)
  287. })
  288. })
  289. this.scene.add(panosGroup)
  290. panosGroup.position.z = panosHeight
  291. this.panosGroup = panosGroup
  292. Potree.Utils.setObjectLayers(panosGroup, 'mapObjects' )
  293. /* e.images.on('markersDisplayChange', (show)=>{
  294. panosGroup.visible = show
  295. this.needRender = true
  296. }) */
  297. //-------
  298. //this.fitPanosToViewport()
  299. this.initFitView()
  300. }
  301. updateClosestPano(intersect){
  302. if(viewer.images360.flying)return;
  303. intersect = intersect && intersect.orthoIntersect
  304. if(!intersect)return
  305. intersect = intersect.clone().setZ(0)
  306. const minDis = 20 //距离鼠标不能太远
  307. var filterFuncs = [
  308. Images360.filters.isEnabled(),
  309. Images360.filters.isVisible(),//只走显示的点,否则会走到别的层
  310. (pano)=>{
  311. return pano.position.clone().setZ(0).distanceTo(intersect) < minDis
  312. },
  313. ];
  314. var pano = Common.find(viewer.images360.panos, filterFuncs, [Images360.sortFunctions.floorDisSquaredToPoint(intersect)]);
  315. if (pano && pano != viewer.images360.currentPano ) {
  316. viewer.images360.flyToPano(pano)
  317. }
  318. }
  319. fitPanosToViewport(){//使所有漫游点占满viewport
  320. //var w = viewer.bound.boundSize.x;
  321. var boundSize = viewer.images360.bound.size.clone().multiplyScalar(1.1);
  322. boundSize.max(new THREE.Vector3(4,4,4))
  323. let endPosition = viewer.images360.bound.center.clone()
  324. this.moveTo(endPosition, boundSize, 0)
  325. }
  326. fitToPointcloud(pointcloud, duration=400){
  327. var boundSize = pointcloud.bound.getSize(new THREE.Vector3)/* .multiplyScalar(1.1); */
  328. boundSize.max(new THREE.Vector3(4,4,4))
  329. let endPosition = pointcloud.bound.getCenter(new THREE.Vector3)
  330. this.moveTo(endPosition, boundSize, duration) //给点duration去变化 否则地图放大后所占的还是很小
  331. }
  332. initFitView(){
  333. let dis = 5 , px = 70 //地图上px像素长度代表的距离为dis //px是手动缩放到5m后发现是这个长度
  334. let zoom = px / dis;
  335. this.camera.zoom = zoom
  336. this.moveTo(viewer.images360.position/* viewer.images360.bound.center */)
  337. this.camera.updateProjectionMatrix()
  338. }
  339. fitToDatasets(datasets){
  340. let bound = new THREE.Box3;
  341. datasets.forEach(e=>bound.union(e.bound))
  342. let center = bound.getCenter(new THREE.Vector3)
  343. let size = bound.getSize(new THREE.Vector3)
  344. this.moveTo(center, size, 200 ) //给duration是为了顺应视口大小改变,缓冲
  345. }
  346. moveTo(endPosition, boundSize, duration=0, margin, easeName ){//前两个参数有xy即可
  347. endPosition = new THREE.Vector3(endPosition.x,endPosition.y,Potree.config.map.cameraHeight)
  348. this.view.moveOrthoCamera(this.viewports[0], {endPosition, boundSize, margin}, duration, easeName)
  349. /* let endZoom, startZoom = this.camera.zoom
  350. //修改相机为bound中心,这样能看到全部(宽度范围内)
  351. this.view.setView({ position:endPosition, duration,
  352. callback:()=>{//done
  353. },
  354. onUpdate:(progress)=>{
  355. if(boundSize){
  356. let aspect = boundSize.x / boundSize.y
  357. let w, h;
  358. if(this.camera.aspect > aspect){//视野更宽则用bound的纵向来决定
  359. h = boundSize.y
  360. //w = h * this.camera.aspect
  361. endZoom = this.viewports[0].resolution.y / h
  362. }else{
  363. w = boundSize.x;
  364. //h = w / this.camera.aspect
  365. endZoom = this.viewports[0].resolution.x / w
  366. }
  367. //onUpdate时更新endzoom是因为画布大小可能更改
  368. this.camera.zoom = endZoom * progress + startZoom * (1 - progress)
  369. this.camera.updateProjectionMatrix()
  370. }
  371. },
  372. Easing:easeName
  373. }) */
  374. }
  375. updateWhenAtViewer(e){//两个触发来源: 1 camera_changed时 2 mapLayer.needUpdate时。 render在viewer中执行
  376. if(this.attachedToViewer){
  377. if(this.started) this.mapLayer.update()
  378. this.needRender = true
  379. }
  380. }
  381. update(delta, areaSize ){
  382. if(!this.visible && !this.attachedToViewer )return
  383. if(this.attachedToViewer){
  384. if(this.mapLayer.needUpdate){
  385. this.updateWhenAtViewer()
  386. }
  387. return
  388. }
  389. this.updateScreenSize()
  390. this.controls.update(delta);
  391. this.view.applyToCamera(this.camera)
  392. let changed = this.cameraChanged()
  393. if(this.started && (changed || this.mapLayer.needUpdate))this.mapLayer.update()
  394. if(changed /*|| || this.needRender */){
  395. /* this.dispatchEvent({
  396. type: "camera_changed",
  397. camera: this.camera,
  398. viewport : this.viewports[0]
  399. }) */
  400. this.mapChanged = true
  401. this.needRender = true
  402. this.updateCursor()//更改大小
  403. }
  404. this.render()
  405. }
  406. attachToMainViewer(state, desc, mapRatio=0.5, options={}){//转移到viewer中。测量时展示or截图需要
  407. if(!Potree.settings.isOfficial)this.renderArea.style.display = state ? 'none':'block'
  408. if(state){
  409. this.enabledOld = this.enabled
  410. this.enabled = true
  411. if(mapRatio != 'dontSet'){
  412. this.changeSplitScreenDir(options.dir, mapRatio)
  413. if(this.attachedToViewer){
  414. //this.fitPanosToViewport()
  415. viewer.updateScreenSize({forceUpdateSize:true})
  416. return
  417. }
  418. viewer.viewports = [viewer.mainViewport, viewer.mapViewer.viewports[0] ];//因为mainViewer的相机变化会触发map的变化,所以先渲染mainViewer
  419. }
  420. if(desc == 'measure') this.inputHandler.registerInteractiveScene(viewer.measuringTool.scene);//虽然用的是viewer的inputHandler,但借用了this.inputHandler的interactiveScenes
  421. else if(desc == 'split4Screens') {
  422. this.inputHandler.registerInteractiveScene(viewer.scene.scene);
  423. }
  424. }else{
  425. if(!this.attachedToViewer)return
  426. viewer.mainViewport.left = 0;
  427. viewer.mainViewport.bottom = 0;
  428. viewer.mainViewport.width = 1;
  429. viewer.mainViewport.height = 1;
  430. this.viewports[0].width = 1;
  431. this.viewports[0].bottom = 0;
  432. this.viewports[0].height = 1;
  433. this.viewports[0].left = 0;
  434. this.inputHandler.unregisterInteractiveScene(viewer.measuringTool.scene);
  435. this.inputHandler.unregisterInteractiveScene(viewer.scene.scene);
  436. viewer.viewports = [viewer.mainViewport]
  437. this.updateScreenSize({forceUpdateSize:true}) //更新相机projectionMatrix
  438. }
  439. //if(desc == 'measure')this.renderMeasure = state
  440. this.attachedToViewer = state
  441. viewer.updateScreenSize({forceUpdateSize:true})
  442. //mapRatio != 'dontSet' && !options.dontFit && this.moveTo(...)//要写在updateScreenSize后面,因为要根据视图大小来fit
  443. if(options.moveToCurrentPos){
  444. let boundSize = new THREE.Vector2(10,10)
  445. let duration = 1000
  446. this.moveTo(viewer.images360.position.clone(), boundSize, duration)
  447. }
  448. this.needRender = true
  449. }
  450. changeSplitScreenDir(dir, mapRatio){//左右 | 上下
  451. //if(!dir || dir == this.dir)return
  452. if(dir )this.splitDir = dir
  453. this.updateSplitSize(mapRatio)
  454. /* if(this.attachedToViewer){ //如果已经分屏了,中途修改方向的话……
  455. this.updateSplitSize()
  456. } */
  457. }
  458. updateSplitSize(mapRatio){
  459. if(mapRatio != void 0) this.mapRatio = mapRatio
  460. //console.log(this.mapRatio)
  461. if(this.splitDir == 'leftRight'){//地图在左方
  462. viewer.mainViewport.left = this.mapRatio
  463. viewer.mainViewport.width = 1-this.mapRatio
  464. this.viewports[0].width = this.mapRatio;
  465. viewer.mainViewport.bottom = this.viewports[0].bottom = 0
  466. viewer.mainViewport.height = this.viewports[0].height = 1
  467. }else if(this.splitDir == 'upDown'){ //地图在下方
  468. viewer.mainViewport.bottom = this.mapRatio
  469. viewer.mainViewport.height = 1-this.mapRatio
  470. this.viewports[0].height = this.mapRatio;
  471. viewer.mainViewport.left = this.viewports[0].left = 0
  472. viewer.mainViewport.width = this.viewports[0].width = 1
  473. }
  474. if(this.attachedToViewer){
  475. viewer.updateScreenSize({forceUpdateSize:true})
  476. }
  477. }
  478. render1(params={}){//viewer的preserveDrawingBuffer为false时的版本
  479. let needCopy, waitCopy
  480. if(!this.visible && !this.attachedToViewer || !this.needRender && !params.force){
  481. if(this.attachedToViewer ){
  482. needCopy = true
  483. }else{
  484. return
  485. }
  486. }
  487. waitCopy = this.attachedToViewer && this.needRender && !params.force//是否写入到copyBuffer。双屏时,若needRender就拷贝到copyBuffer中,双屏时就直接使用copyBuffer。 四屏时因渲染点云会每帧都渲染,所以不需要缓存。
  488. let renderer = params.renderer || this.renderer
  489. if(waitCopy){
  490. this.copyBuffer.setSize(params.viewport.resolution2.x, params.viewport.resolution2.y)
  491. renderer.setRenderTarget(this.copyBuffer)
  492. }else if(params.target){
  493. renderer.setRenderTarget(params.target)
  494. }
  495. /* if(params.resize){
  496. this.emitResizeMsg(new THREE.Vector2(params.width,params.height, viewport:params.viewport))
  497. } */
  498. params.clear ? params.clear() : renderer.clear();
  499. if(!needCopy || waitCopy){//重绘
  500. viewer.dispatchEvent({type: "render.begin", viewer: this, viewport:this.viewports[0], params });
  501. Potree.Utils.setCameraLayers(this.camera, ['map','mapObjects' , 'bothMapAndScene' ])
  502. if(this.mapGradientBG){//渲染背景
  503. viewer.scene.cameraBG.layers.set(Potree.config.renderLayers.bg);
  504. renderer.render(viewer.scene.scene, viewer.scene.cameraBG);
  505. }
  506. renderer.render(this.scene, this.camera);
  507. renderer.render(viewer.scene.scene, this.camera);
  508. //测量线等
  509. //params.renderOverlay && params.renderOverlay( $.extend({}, params, { isMap:true }))
  510. renderer.setRenderTarget(params.target||null)
  511. }
  512. if(needCopy || waitCopy){//使用缓存 ----当viewer的preserveDrawingBuffer为false的话,使用buffer
  513. this.copyPass.render(null,null, null, renderer, params.target||null, this.copyBuffer)
  514. }
  515. this.needRender = false
  516. return true
  517. }
  518. //拆成两次渲染,一个地图一个其他物体,且地图渲染后保存在buffer中,只有当地图变化后才重渲染。
  519. render(params={}){
  520. if(!this.visible && !this.attachedToViewer || !this.needRender && !params.force){ //注意:mapViewer.needRender的权重高于它的viewport的needRender,也就是说,当attachedToViewer时,viewer即使needRender, mapViewer也不一定会渲染。
  521. return
  522. }
  523. viewer.addTimeMark('mapRender','start')
  524. let renderer = params.renderer || this.renderer
  525. if(this.mapChanged){ //渲染地图背景
  526. renderer.setRenderTarget(this.copyBuffer)
  527. params.clear ? params.clear() : renderer.clear();
  528. if(this.mapGradientBG){//渲染背景
  529. viewer.scene.cameraBG.layers.set(Potree.config.renderLayers.bg);
  530. renderer.render(viewer.scene.scene, viewer.scene.cameraBG);
  531. }
  532. Potree.Utils.setCameraLayers(this.camera, ['map'])
  533. renderer.render(this.scene, this.camera);
  534. params.renderBG && params.renderBG(this.viewports[0])
  535. this.mapChanged = false
  536. renderer.setRenderTarget(params.target||null)
  537. }
  538. params.clear ? params.clear() : renderer.clear();
  539. this.copyPass.render(null,null, null,renderer, params.target||null, this.copyBuffer) //拷贝地图背景
  540. renderer.clearDepth(); //防止地图遮挡其他物体
  541. //绘制其他物体
  542. Potree.Utils.setCameraLayers(this.camera, ['mapObjects' , 'bothMapAndScene' ])
  543. viewer.dispatchEvent({type: "render.begin", viewer: this, viewport:this.viewports[0], params });
  544. renderer.render(this.scene, this.camera);
  545. this.attachedToViewer || renderer.render(viewer.scene.scene, this.camera); //类同renderOverlay
  546. renderer.setRenderTarget(null)
  547. this.needRender = false
  548. viewer.addTimeMark('mapRender','end')
  549. return true
  550. }
  551. }
  552. /*
  553. 渲染顺序:
  554. 地图
  555. 背景Overlay
  556. 地图scene的物体,如cursor、 marker
  557. 点云(如果有)
  558. overlay,两层:第一层:viewer的scene中bothMapAndScene的如reticule. 第二层:如测量线(attachToMainViewer时才渲染)
  559. */
  560. //本地调试地图白屏是因为代码自动更新了 但没刷新