diff --git a/examples/3dtiles.html b/examples/3dtiles.html index 56e31f5466..68f3a681f1 100644 --- a/examples/3dtiles.html +++ b/examples/3dtiles.html @@ -55,7 +55,7 @@ // Add the UI Debug var d = new debug.Debug(view, menuGlobe.gui); - debug.createTileDebugUI(menuGlobe.gui, view, view.wgs84TileLayer, d); + debug.createTileDebugUI(menuGlobe.gui, view, view.tileLayer, d); debug.create3dTilesDebugUI(menuGlobe.gui, view, $3dTilesLayerDiscreteLOD, d); debug.create3dTilesDebugUI(menuGlobe.gui, view, $3dTilesLayerRequestVolume, d); d.zoom = function() { diff --git a/examples/globe_vector_tiles.html b/examples/globe_vector_tiles.html index d76e99c950..af32d6e084 100644 --- a/examples/globe_vector_tiles.html +++ b/examples/globe_vector_tiles.html @@ -31,7 +31,7 @@ var view = new itowns.GlobeView(viewerDiv, positionOnGlobe, { maxSubdivisionLevel: 13 }); // define pole texture - view.wgs84TileLayer.noTextureColor = new itowns.THREE.Color(0x95c1e1); + view.tileLayer.noTextureColor = new itowns.THREE.Color(0x95c1e1); view.atmosphere.visible = false; diff --git a/examples/globe_wfs_color.html b/examples/globe_wfs_color.html index 3c4738638b..1a232a1d5b 100644 --- a/examples/globe_wfs_color.html +++ b/examples/globe_wfs_color.html @@ -90,7 +90,7 @@ console.info('Globe initialized'); itowns.ColorLayersOrdering.moveLayerToIndex(globeView, 'Ortho', 0); }); - debug.createTileDebugUI(menuGlobe.gui, globeView, globeView.wgs84TileLayer, d); + debug.createTileDebugUI(menuGlobe.gui, globeView, globeView.tileLayer, d); diff --git a/examples/globe_wfs_extruded.html b/examples/globe_wfs_extruded.html index ca5bff671b..1a755f8d58 100644 --- a/examples/globe_wfs_extruded.html +++ b/examples/globe_wfs_extruded.html @@ -60,7 +60,7 @@ var i = 0; var result; var tile; - var layer = globeView.wgs84TileLayer; + var layer = globeView.tileLayer; if (contour.length && contour.length > 0) { for (; i < contour.length; i++) { result = itowns.DEMUtils.getElevationValueAt(layer, contour[i], 0, tile); @@ -210,7 +210,7 @@ var result; var z = 0; if (contour.length && contour.length > 0) { - result = itowns.DEMUtils.getElevationValueAt(globeView.wgs84TileLayer, contour[0]); + result = itowns.DEMUtils.getElevationValueAt(globeView.tileLayer, contour[0]); if (result) { z = result.z; } @@ -255,7 +255,7 @@ globeView.controls.setTilt(45, true); }); var d = new debug.Debug(globeView, menuGlobe.gui); - debug.createTileDebugUI(menuGlobe.gui, globeView, globeView.wgs84TileLayer, d); + debug.createTileDebugUI(menuGlobe.gui, globeView, globeView.tileLayer, d); function picking(event) { var htmlInfo = document.getElementById('info'); diff --git a/examples/orientation_utils.html b/examples/orientation_utils.html index 7c5db1193a..41736e004d 100644 --- a/examples/orientation_utils.html +++ b/examples/orientation_utils.html @@ -17,7 +17,7 @@ diff --git a/examples/panorama.html b/examples/panorama.html index bb1e979e04..be58eb4315 100644 --- a/examples/panorama.html +++ b/examples/panorama.html @@ -71,8 +71,8 @@ // Setup debug menu var gui = new dat.GUI(); var ddd = new debug.Debug(view, gui); - debug.createTileDebugUI(gui, view, view.baseLayer, ddd); - gui.add(view.baseLayer.options, 'quality').min(0.1).max(1.0).onChange( + debug.createTileDebugUI(gui, view, view.tileLayer, ddd); + gui.add(view.tileLayer.options, 'quality').min(0.1).max(1.0).onChange( function () { view.notifyChange(); }); // Add controls diff --git a/examples/stereo.html b/examples/stereo.html index 5f09607a40..15cd1ae0ad 100644 --- a/examples/stereo.html +++ b/examples/stereo.html @@ -164,7 +164,7 @@ var divScaleWidget = document.querySelectorAll('.divScaleWidget')[0]; var d = new debug.Debug(globeView, menuGlobe.gui); - debug.createTileDebugUI(menuGlobe.gui, globeView, globeView.wgs84TileLayer, d); + debug.createTileDebugUI(menuGlobe.gui, globeView, globeView.tileLayer, d); function updateScaleWidget() { var value = globeView.controls.pixelsToMeters(200); diff --git a/examples/syncCameras.html b/examples/syncCameras.html index aac11a5052..1a4eb6a758 100644 --- a/examples/syncCameras.html +++ b/examples/syncCameras.html @@ -149,7 +149,7 @@ }, }); var d = new debug.Debug(globeView, menuGlobe.gui); - debug.createTileDebugUI(menuGlobe.gui, globeView, globeView.wgs84TileLayer, d); + debug.createTileDebugUI(menuGlobe.gui, globeView, globeView.tileLayer, d); diff --git a/index.html b/index.html index 59d01f17bc..19c24d532d 100644 --- a/index.html +++ b/index.html @@ -69,7 +69,7 @@ }); const d = new debug.Debug(globeView, menuGlobe.gui); - debug.createTileDebugUI(menuGlobe.gui, globeView, globeView.wgs84TileLayer, d); + debug.createTileDebugUI(menuGlobe.gui, globeView, globeView.tileLayer, d); window.globeView = globeView; diff --git a/src/Core/Prefab/GlobeView.js b/src/Core/Prefab/GlobeView.js index 59d52dc9b4..8815c48c5b 100644 --- a/src/Core/Prefab/GlobeView.js +++ b/src/Core/Prefab/GlobeView.js @@ -1,7 +1,7 @@ import * as THREE from 'three'; import View, { VIEW_EVENTS } from '../View'; -import { RENDERING_PAUSED, MAIN_LOOP_EVENTS } from '../MainLoop'; +import { MAIN_LOOP_EVENTS } from '../MainLoop'; import { COLOR_LAYERS_ORDER_CHANGED } from '../../Renderer/ColorLayersOrdering'; import RendererConstant from '../../Renderer/RendererConstant'; import GlobeControls from '../../Renderer/ThreeExtended/GlobeControls'; @@ -97,14 +97,14 @@ function GlobeView(viewerDiv, coordCarto, options = {}) { this.camera.camera3D.near = Math.max(15.0, 0.000002352 * size); this.camera.camera3D.far = size * 10; - const wgs84TileLayer = new GlobeLayer('globe', options.object3d); + const tileLayer = new GlobeLayer('globe', options.object3d); const sun = new THREE.DirectionalLight(); sun.position.set(-0.5, 0, 1); sun.updateMatrixWorld(true); - wgs84TileLayer.object3d.add(sun); + tileLayer.object3d.add(sun); - this.addLayer(wgs84TileLayer); + this.addLayer(tileLayer); // Atmosphere this.atmosphere = new Atmosphere(); @@ -113,7 +113,7 @@ function GlobeView(viewerDiv, coordCarto, options = {}) { this.atmosphere.traverse((obj) => { obj.layers.set(atmosphereLayer); }); this.camera.camera3D.layers.enable(atmosphereLayer); - wgs84TileLayer.object3d.add(this.atmosphere); + tileLayer.object3d.add(this.atmosphere); this.atmosphere.updateMatrixWorld(true); @@ -151,9 +151,9 @@ function GlobeView(viewerDiv, coordCarto, options = {}) { this.addFrameRequester(MAIN_LOOP_EVENTS.AFTER_CAMERA_UPDATE, () => { const v = new THREE.Vector3(); - v.setFromMatrixPosition(wgs84TileLayer.object3d.matrixWorld); + v.setFromMatrixPosition(tileLayer.object3d.matrixWorld); var len = v.distanceTo(this.camera.camera3D.position); - v.setFromMatrixScale(wgs84TileLayer.object3d.matrixWorld); + v.setFromMatrixScale(tileLayer.object3d.matrixWorld); // Compute fog distance, this function makes it possible to have a shorter distance // when the camera approaches the ground @@ -174,7 +174,7 @@ function GlobeView(viewerDiv, coordCarto, options = {}) { } }); - this.wgs84TileLayer = wgs84TileLayer; + this.tileLayer = tileLayer; const fn = () => { this.removeEventListener(VIEW_EVENTS.LAYERS_INITIALIZED, fn); @@ -200,7 +200,7 @@ GlobeView.prototype.addLayer = function addLayer(layer) { } } const layerId = layer.id; - const layerPromise = View.prototype.addLayer.call(this, layer, this.wgs84TileLayer); + const layerPromise = View.prototype.addLayer.call(this, layer, this.tileLayer); this.dispatchEvent({ type: GLOBE_VIEW_EVENTS.LAYER_ADDED, @@ -219,14 +219,14 @@ GlobeView.prototype.addLayer = function addLayer(layer) { */ GlobeView.prototype.removeLayer = function removeImageryLayer(layerId) { const layer = this.getLayers(l => l.id === layerId)[0]; - if (layer && layer.type === 'color' && this.wgs84TileLayer.detach(layer)) { + if (layer && layer.type === 'color' && this.tileLayer.detach(layer)) { var cO = function cO(object) { if (object.removeColorLayer) { object.removeColorLayer(layerId); } }; - for (const root of this.wgs84TileLayer.level0Nodes) { + for (const root of this.tileLayer.level0Nodes) { root.traverse(cO); } const imageryLayers = this.getLayers(l => l.type === 'color'); @@ -236,7 +236,7 @@ GlobeView.prototype.removeLayer = function removeImageryLayer(layerId) { } } - this.notifyChange(this.wgs84TileLayer); + this.notifyChange(this.tileLayer); this.dispatchEvent({ type: GLOBE_VIEW_EVENTS.LAYER_REMOVED, layerId, @@ -249,10 +249,10 @@ GlobeView.prototype.removeLayer = function removeImageryLayer(layerId) { }; GlobeView.prototype.selectNodeAt = function selectNodeAt(mouse) { - const picked = this.wgs84TileLayer.pickObjectsAt(this, mouse); + const picked = this.tileLayer.pickObjectsAt(this, mouse); const selectedId = picked.length ? picked[0].object.id : undefined; - for (const n of this.wgs84TileLayer.level0Nodes) { + for (const n of this.tileLayer.level0Nodes) { n.traverse((node) => { // only take of selectable nodes if (node.setSelected) { @@ -269,119 +269,12 @@ GlobeView.prototype.selectNodeAt = function selectNodeAt(mouse) { this.notifyChange(); }; -GlobeView.prototype.readDepthBuffer = function readDepthBuffer(x, y, width, height) { - const g = this.mainLoop.gfxEngine; - const currentWireframe = this.wgs84TileLayer.wireframe; - const currentOpacity = this.wgs84TileLayer.opacity; - const currentVisibility = this.wgs84TileLayer.visible; - if (currentWireframe) { - this.wgs84TileLayer.wireframe = false; - } - if (currentOpacity < 1.0) { - this.wgs84TileLayer.opacity = 1.0; - } - if (!currentVisibility) { - this.wgs84TileLayer.visible = true; - } - - const restore = this.wgs84TileLayer.level0Nodes.map(n => n.pushRenderState(RendererConstant.DEPTH)); - const buffer = g.renderViewToBuffer( - { camera: this.camera, scene: this.wgs84TileLayer.object3d }, - { x, y, width, height }); - restore.forEach(r => r()); - - if (this.wgs84TileLayer.wireframe !== currentWireframe) { - this.wgs84TileLayer.wireframe = currentWireframe; - } - if (this.wgs84TileLayer.opacity !== currentOpacity) { - this.wgs84TileLayer.opacity = currentOpacity; - } - if (this.wgs84TileLayer.visible !== currentVisibility) { - this.wgs84TileLayer.visible = currentVisibility; - } - - return buffer; -}; - -const matrix = new THREE.Matrix4(); -const screen = new THREE.Vector2(); -const ray = new THREE.Ray(); -const direction = new THREE.Vector3(); - -/** - * Returns the world position (view's crs: referenceCrs) under view coordinates. - * This position is computed with depth buffer. - * - * @param {THREE.Vector2} mouse position in view coordinates (in pixel), if it's null so it's view's center. - * @param {THREE.Vector3} [target=THREE.Vector3()] target the result will be copied into this Vector3. If not present a new one will be created. - * @return {THREE.Vector3} the world position in view's crs: referenceCrs. - */ - -GlobeView.prototype.getPickingPositionFromDepth = function getPickingPositionFromDepth(mouse, target = new THREE.Vector3()) { - if (!this.wgs84TileLayer || this.wgs84TileLayer.level0Nodes.length == 0) { - target = undefined; - return; - } - const l = this.mainLoop; - const viewPaused = l.scheduler.commandsWaitingExecutionCount() == 0 && l.renderingState == RENDERING_PAUSED; - const g = l.gfxEngine; - const dim = g.getWindowSize(); - const camera = this.camera.camera3D; - - mouse = mouse || dim.clone().multiplyScalar(0.5); - mouse.x = Math.floor(mouse.x); - mouse.y = Math.floor(mouse.y); - - const prev = camera.layers.mask; - camera.layers.mask = 1 << this.wgs84TileLayer.threejsLayer; - - // Render/Read to buffer - let buffer; - if (viewPaused) { - this._fullSizeDepthBuffer = this._fullSizeDepthBuffer || this.readDepthBuffer(0, 0, dim.x, dim.y); - const id = ((dim.y - mouse.y - 1) * dim.x + mouse.x) * 4; - buffer = this._fullSizeDepthBuffer.slice(id, id + 4); - } else { - buffer = this.readDepthBuffer(mouse.x, mouse.y, 1, 1); - } - - screen.x = (mouse.x / dim.x) * 2 - 1; - screen.y = -(mouse.y / dim.y) * 2 + 1; - - // Origin - ray.origin.copy(camera.position); - - // Direction - ray.direction.set(screen.x, screen.y, 0.5); - // Unproject - matrix.multiplyMatrices(camera.matrixWorld, matrix.getInverse(camera.projectionMatrix)); - ray.direction.applyMatrix4(matrix); - ray.direction.sub(ray.origin); - - direction.set(0, 0, 1.0); - direction.applyMatrix4(matrix); - direction.sub(ray.origin); - - const angle = direction.angleTo(ray.direction); - const orthoZ = g.depthBufferRGBAValueToOrthoZ(buffer, camera); - const length = orthoZ / Math.cos(angle); - - target.addVectors(camera.position, ray.direction.setLength(length)); - - camera.layers.mask = prev; - - if (target.length() > 10000000) - { return undefined; } - - return target; -}; - GlobeView.prototype.setRealisticLightingOn = function setRealisticLightingOn(value) { const coSun = CoordStars.getSunPositionInScene(new Date().getTime(), 48.85, 2.35).normalize(); this.lightingPos = coSun.normalize(); - const lighting = this.wgs84TileLayer.lighting; + const lighting = this.tileLayer.lighting; lighting.enable = value; lighting.position = coSun; @@ -390,18 +283,18 @@ GlobeView.prototype.setRealisticLightingOn = function setRealisticLightingOn(val this.updateMaterialUniform('lightingEnabled', value); this.updateMaterialUniform('lightPosition', coSun); - this.notifyChange(this.wgs84TileLayer); + this.notifyChange(this.tileLayer); }; GlobeView.prototype.setLightingPos = function setLightingPos(pos) { const lightingPos = pos || CoordStars.getSunPositionInScene(this.ellipsoid, new Date().getTime(), 48.85, 2.35); this.updateMaterialUniform('lightPosition', lightingPos.clone().normalize()); - this.notifyChange(this.wgs84TileLayer); + this.notifyChange(this.tileLayer); }; GlobeView.prototype.updateMaterialUniform = function updateMaterialUniform(uniformName, value) { - for (const n of this.wgs84TileLayer.level0Nodes) { + for (const n of this.tileLayer.level0Nodes) { n.traverse((obj) => { if (!obj.material || !obj.material.uniforms) { return; diff --git a/src/Core/Prefab/PanoramaView.js b/src/Core/Prefab/PanoramaView.js index f54a1d71d0..e9667ec55d 100644 --- a/src/Core/Prefab/PanoramaView.js +++ b/src/Core/Prefab/PanoramaView.js @@ -30,11 +30,9 @@ function PanoramaView(viewerDiv, coordinates, type, options = {}) { } camera.updateMatrixWorld(); - const tileLayer = new PanoramaLayer('panorama', coordinates, type, options); + this.tileLayer = new PanoramaLayer('panorama', coordinates, type, options); - View.prototype.addLayer.call(this, tileLayer); - - this.baseLayer = tileLayer; + View.prototype.addLayer.call(this, this.tileLayer); } PanoramaView.prototype = Object.create(View.prototype); @@ -47,7 +45,7 @@ PanoramaView.prototype.addLayer = function addLayer(layer) { if (layer.type != 'color') { throw new Error(`Unsupported layer type ${layer.type} (PanoramaView only support 'color' layers)`); } - return View.prototype.addLayer.call(this, layer, this.baseLayer); + return View.prototype.addLayer.call(this, layer, this.tileLayer); }; export default PanoramaView; diff --git a/src/Core/Prefab/PlanarView.js b/src/Core/Prefab/PlanarView.js index 97845371d4..c4076e75bf 100644 --- a/src/Core/Prefab/PlanarView.js +++ b/src/Core/Prefab/PlanarView.js @@ -1,7 +1,7 @@ import * as THREE from 'three'; import View from '../View'; -import { RENDERING_PAUSED, MAIN_LOOP_EVENTS } from '../MainLoop'; +import { MAIN_LOOP_EVENTS } from '../MainLoop'; import RendererConstant from '../../Renderer/RendererConstant'; import CameraUtils from '../../utils/CameraUtils'; @@ -73,114 +73,4 @@ PlanarView.prototype.selectNodeAt = function selectNodeAt(mouse) { this.notifyChange(); }; - -PlanarView.prototype.readDepthBuffer = function readDepthBuffer(x, y, width, height) { - const g = this.mainLoop.gfxEngine; - const currentWireframe = this.tileLayer.wireframe; - const currentOpacity = this.tileLayer.opacity; - const currentVisibility = this.tileLayer.visible; - if (currentWireframe) { - this.tileLayer.wireframe = false; - } - if (currentOpacity < 1.0) { - this.tileLayer.opacity = 1.0; - } - if (!currentVisibility) { - this.tileLayer.visible = true; - } - const restoreState = this.tileLayer.level0Nodes[0].pushRenderState(RendererConstant.DEPTH); - const buffer = g.renderViewToBuffer( - { camera: this.camera, scene: this.tileLayer.object3d }, - { x, y, width, height }); - restoreState(); - if (this.tileLayer.wireframe !== currentWireframe) { - this.tileLayer.wireframe = currentWireframe; - } - if (this.tileLayer.opacity !== currentOpacity) { - this.tileLayer.opacity = currentOpacity; - } - if (this.tileLayer.visible !== currentVisibility) { - this.tileLayer.visible = currentVisibility; - } - return buffer; -}; - -const matrix = new THREE.Matrix4(); -const screen = new THREE.Vector2(); -const ray = new THREE.Ray(); -const direction = new THREE.Vector3(); - -/** - * Returns the world position (view's crs: referenceCrs) under view coordinates. - * This position is computed with depth buffer. - * - * @param {THREE.Vector2} mouse position in view coordinates (in pixel), if it's null so it's view's center. - * @param {THREE.Vector3} [target=THREE.Vector3()] target. the result will be copied into this Vector3. If not present a new one will be created. - * @return {THREE.Vector3} the world position in view's crs: referenceCrs. - */ - -PlanarView.prototype.getPickingPositionFromDepth = function getPickingPositionFromDepth(mouse, target = new THREE.Vector3()) { - if (!this.tileLayer || this.tileLayer.level0Nodes.length == 0) { - target = undefined; - return; - } - const l = this.mainLoop; - if (!this.tileLayer.level0Nodes[0]) { - target = undefined; - return; - } - const viewPaused = l.scheduler.commandsWaitingExecutionCount() == 0 && l.renderingState == RENDERING_PAUSED; - const g = l.gfxEngine; - const dim = g.getWindowSize(); - const camera = this.camera.camera3D; - - mouse = mouse || dim.clone().multiplyScalar(0.5); - mouse.x = Math.floor(mouse.x); - mouse.y = Math.floor(mouse.y); - - // Prepare state - const prev = camera.layers.mask; - camera.layers.mask = 1 << this.tileLayer.threejsLayer; - - // Render/Read to buffer - let buffer; - if (viewPaused) { - this._fullSizeDepthBuffer = this._fullSizeDepthBuffer || this.readDepthBuffer(0, 0, dim.x, dim.y); - const id = ((dim.y - mouse.y - 1) * dim.x + mouse.x) * 4; - buffer = this._fullSizeDepthBuffer.slice(id, id + 4); - } else { - buffer = this.readDepthBuffer(mouse.x, mouse.y, 1, 1); - } - - screen.x = (mouse.x / dim.x) * 2 - 1; - screen.y = -(mouse.y / dim.y) * 2 + 1; - - // Origin - ray.origin.copy(camera.position); - - // Direction - ray.direction.set(screen.x, screen.y, 0.5); - // Unproject - matrix.multiplyMatrices(camera.matrixWorld, matrix.getInverse(camera.projectionMatrix)); - ray.direction.applyMatrix4(matrix); - ray.direction.sub(ray.origin); - - direction.set(0, 0, 1.0); - direction.applyMatrix4(matrix); - direction.sub(ray.origin); - - const angle = direction.angleTo(ray.direction); - const orthoZ = g.depthBufferRGBAValueToOrthoZ(buffer, camera); - const length = orthoZ / Math.cos(angle); - - target.addVectors(camera.position, ray.direction.setLength(length)); - - camera.layers.mask = prev; - - if (target.length() > 10000000) - { return undefined; } - - return target; -}; - export default PlanarView; diff --git a/src/Core/View.js b/src/Core/View.js index c41bc9099a..5ef36c5a76 100644 --- a/src/Core/View.js +++ b/src/Core/View.js @@ -3,6 +3,7 @@ import * as THREE from 'three'; import Camera from '../Renderer/Camera'; import MainLoop, { MAIN_LOOP_EVENTS, RENDERING_PAUSED } from './MainLoop'; import c3DEngine from '../Renderer/c3DEngine'; +import RendererConstant from '../Renderer/RendererConstant'; import { getMaxColorSamplerUnitsCount } from '../Renderer/LayeredMaterial'; @@ -623,4 +624,112 @@ View.prototype.pickObjectsAt = function pickObjectsAt(mouseOrEvt, radius, ...whe return results; }; +View.prototype.readDepthBuffer = function readDepthBuffer(x, y, width, height) { + const g = this.mainLoop.gfxEngine; + const currentWireframe = this.tileLayer.wireframe; + const currentOpacity = this.tileLayer.opacity; + const currentVisibility = this.tileLayer.visible; + if (currentWireframe) { + this.tileLayer.wireframe = false; + } + if (currentOpacity < 1.0) { + this.tileLayer.opacity = 1.0; + } + if (!currentVisibility) { + this.tileLayer.visible = true; + } + + const restore = this.tileLayer.level0Nodes.map(n => n.pushRenderState(RendererConstant.DEPTH)); + const buffer = g.renderViewToBuffer( + { camera: this.camera, scene: this.tileLayer.object3d }, + { x, y, width, height }); + restore.forEach(r => r()); + + if (this.tileLayer.wireframe !== currentWireframe) { + this.tileLayer.wireframe = currentWireframe; + } + if (this.tileLayer.opacity !== currentOpacity) { + this.tileLayer.opacity = currentOpacity; + } + if (this.tileLayer.visible !== currentVisibility) { + this.tileLayer.visible = currentVisibility; + } + + return buffer; +}; + +const matrix = new THREE.Matrix4(); +const screen = new THREE.Vector2(); +const ray = new THREE.Ray(); +const direction = new THREE.Vector3(); + +/** + * Returns the world position (view's crs: referenceCrs) under view coordinates. + * This position is computed with depth buffer. + * + * @param {THREE.Vector2} mouse position in view coordinates (in pixel), if it's null so it's view's center. + * @param {THREE.Vector3} [target=THREE.Vector3()] target. the result will be copied into this Vector3. If not present a new one will be created. + * @return {THREE.Vector3} the world position in view's crs: referenceCrs. + */ + +View.prototype.getPickingPositionFromDepth = function fnGetPickingPositionFromDepth(mouse, target = new THREE.Vector3()) { + if (!this.tileLayer || this.tileLayer.level0Nodes.length == 0 || (!this.tileLayer.level0Nodes[0])) { + target = undefined; + return; + } + const l = this.mainLoop; + const viewPaused = l.scheduler.commandsWaitingExecutionCount() == 0 && l.renderingState == RENDERING_PAUSED; + const g = l.gfxEngine; + const dim = g.getWindowSize(); + const camera = this.camera.camera3D; + + mouse = mouse || dim.clone().multiplyScalar(0.5); + mouse.x = Math.floor(mouse.x); + mouse.y = Math.floor(mouse.y); + + // Prepare state + const prev = camera.layers.mask; + camera.layers.mask = 1 << this.tileLayer.threejsLayer; + + // Render/Read to buffer + let buffer; + if (viewPaused) { + this._fullSizeDepthBuffer = this._fullSizeDepthBuffer || this.readDepthBuffer(0, 0, dim.x, dim.y); + const id = ((dim.y - mouse.y - 1) * dim.x + mouse.x) * 4; + buffer = this._fullSizeDepthBuffer.slice(id, id + 4); + } else { + buffer = this.readDepthBuffer(mouse.x, mouse.y, 1, 1); + } + + screen.x = (mouse.x / dim.x) * 2 - 1; + screen.y = -(mouse.y / dim.y) * 2 + 1; + + // Origin + ray.origin.copy(camera.position); + + // Direction + ray.direction.set(screen.x, screen.y, 0.5); + // Unproject + matrix.multiplyMatrices(camera.matrixWorld, matrix.getInverse(camera.projectionMatrix)); + ray.direction.applyMatrix4(matrix); + ray.direction.sub(ray.origin); + + direction.set(0, 0, 1.0); + direction.applyMatrix4(matrix); + direction.sub(ray.origin); + + const angle = direction.angleTo(ray.direction); + const orthoZ = g.depthBufferRGBAValueToOrthoZ(buffer, camera); + const length = orthoZ / Math.cos(angle); + + target.addVectors(camera.position, ray.direction.setLength(length)); + + camera.layers.mask = prev; + + if (target.length() > 10000000) + { return undefined; } + + return target; +}; + export default View; diff --git a/src/Renderer/ColorLayersOrdering.js b/src/Renderer/ColorLayersOrdering.js index 0df3348fff..0f81438e6a 100644 --- a/src/Renderer/ColorLayersOrdering.js +++ b/src/Renderer/ColorLayersOrdering.js @@ -30,12 +30,12 @@ export const ColorLayersOrdering = { if (layer) { const previousSequence = ImageryLayers.getColorLayersIdOrderedBySequence(imageryLayers); ImageryLayers.moveLayerUp(layer, imageryLayers); - updateLayersOrdering(view.wgs84TileLayer, imageryLayers); + updateLayersOrdering(view.tileLayer, imageryLayers); view.dispatchEvent({ type: COLOR_LAYERS_ORDER_CHANGED, previous: { sequence: previousSequence }, new: { sequence: ImageryLayers.getColorLayersIdOrderedBySequence(imageryLayers) }, }); - view.notifyChange(view.wgs84TileLayer); + view.notifyChange(view.tileLayer); } else { throw new Error(`${layerId} isn't color layer`); } @@ -54,12 +54,12 @@ export const ColorLayersOrdering = { if (layer) { const previousSequence = ImageryLayers.getColorLayersIdOrderedBySequence(imageryLayers); ImageryLayers.moveLayerDown(layer, imageryLayers); - updateLayersOrdering(view.wgs84TileLayer, imageryLayers); + updateLayersOrdering(view.tileLayer, imageryLayers); view.dispatchEvent({ type: COLOR_LAYERS_ORDER_CHANGED, previous: { sequence: previousSequence }, new: { sequence: ImageryLayers.getColorLayersIdOrderedBySequence(imageryLayers) }, }); - view.notifyChange(view.wgs84TileLayer); + view.notifyChange(view.tileLayer); } else { throw new Error(`${layerId} isn't color layer`); } @@ -79,12 +79,12 @@ export const ColorLayersOrdering = { if (layer) { const previousSequence = ImageryLayers.getColorLayersIdOrderedBySequence(imageryLayers); ImageryLayers.moveLayerToIndex(layer, newIndex, imageryLayers); - updateLayersOrdering(view.wgs84TileLayer, imageryLayers); + updateLayersOrdering(view.tileLayer, imageryLayers); view.dispatchEvent({ type: COLOR_LAYERS_ORDER_CHANGED, previous: { sequence: previousSequence }, new: { sequence: ImageryLayers.getColorLayersIdOrderedBySequence(imageryLayers) }, }); - view.notifyChange(view.wgs84TileLayer); + view.notifyChange(view.tileLayer); } else { throw new Error(`${layerId} isn't color layer`); } diff --git a/src/Renderer/ThreeExtended/GlobeControls.js b/src/Renderer/ThreeExtended/GlobeControls.js index 3ce871cfc6..113b7aecb4 100644 --- a/src/Renderer/ThreeExtended/GlobeControls.js +++ b/src/Renderer/ThreeExtended/GlobeControls.js @@ -322,9 +322,9 @@ function GlobeControls(view, targetCoordinate, range, globeRadius, options = {}) // Depending on the distance of the camera with obbs, we add a slowdown or constrain to the movement. // this constraint or deceleration is suitable for two types of movement MOVE_GLOBE and ORBIT. // This constraint or deceleration inversely proportional to the camera/obb distance - if (view.wgs84TileLayer) { + if (view.tileLayer) { minDistanceZ = Infinity; - for (const tile of view.wgs84TileLayer.level0Nodes) { + for (const tile of view.tileLayer.level0Nodes) { tile.traverse(getMinDistanceCameraBoundingSphereObbsUp); } } diff --git a/test/examples/globe.js b/test/examples/globe.js index 17ff5bf532..cdd9c5475b 100644 --- a/test/examples/globe.js +++ b/test/examples/globe.js @@ -32,10 +32,10 @@ describe('globe', () => { this.test.fullTitle()); const maxColorSamplerUnitsCount = await page - .evaluate(type => globeView.wgs84TileLayer.level0Nodes[0] + .evaluate(type => globeView.tileLayer.level0Nodes[0] .material.textures[type].length, 1); const colorSamplerUnitsCount = await page.evaluate(() => - globeView.wgs84TileLayer.countColorLayersTextures(globeView.getLayers(l => l.type === 'color')[0])); + globeView.tileLayer.countColorLayersTextures(globeView.getLayers(l => l.type === 'color')[0])); const limit = maxColorSamplerUnitsCount - colorSamplerUnitsCount; // add layers just below the capacity limit diff --git a/utils/debug/Debug.js b/utils/debug/Debug.js index 5b27081396..d4b12fd542 100644 --- a/utils/debug/Debug.js +++ b/utils/debug/Debug.js @@ -31,7 +31,7 @@ function Debug(view, datDebugTool, chartDivContainer) { this.charts.push(new ThreeStatsChart('three-info', view.mainLoop.gfxEngine.renderer)); const charts = this.charts; - const tileLayer = view.tileLayer || view.wgs84TileLayer || view.baseLayer; + const tileLayer = view.tileLayer; function debugChartUpdate(updateDuration) { const displayed = chartDivContainer.style.display != 'none';