From e44de7fb9dc5e479ae787363d4dc7328097f5ad2 Mon Sep 17 00:00:00 2001 From: mgermerie <73115044+mgermerie@users.noreply.github.com> Date: Tue, 9 Feb 2021 16:24:01 +0100 Subject: [PATCH] fix(Camera): resize preserves the scale --- src/Renderer/Camera.js | 30 ++++++++++++++++++++---------- test/unit/camera.js | 22 +++++++++++++++++++++- 2 files changed, 41 insertions(+), 11 deletions(-) diff --git a/src/Renderer/Camera.js b/src/Renderer/Camera.js index 659b7c147a..b9dfbb81b6 100644 --- a/src/Renderer/Camera.js +++ b/src/Renderer/Camera.js @@ -115,6 +115,7 @@ class Camera { break; } } + this.camera3D.aspect = this.camera3D.aspect !== undefined ? this.camera3D.aspect : 1; this._viewMatrix = new THREE.Matrix4(); this.width = width; @@ -136,23 +137,32 @@ class Camera { } } + /** + * Resize the camera to a given width and height + * + * @param {number} width The width to resize the camera to. + * @param {number} height The height to resize the camera to. + */ resize(width, height) { - this.width = width; - this.height = height; - const ratio = width / height; - updatePreSse(this, this.height, this.camera3D.fov); - if (this.camera3D.aspect !== ratio) { - this.camera3D.aspect = ratio; if (this.camera3D.isOrthographicCamera) { - const halfH = (this.camera3D.right - this.camera3D.left) * 0.5 / ratio; - const y = (this.camera3D.top + this.camera3D.bottom) * 0.5; - this.camera3D.top = y + halfH; - this.camera3D.bottom = y - halfH; + this.camera3D.zoom *= this.width / width; + const halfH = this.camera3D.top * this.camera3D.aspect / ratio; + this.camera3D.bottom = -halfH; + this.camera3D.top = halfH; + } else if (this.camera3D.isPerspectiveCamera) { + this.camera3D.fov = 2 * THREE.Math.radToDeg(Math.atan( + (height / this.height) * Math.tan(THREE.Math.degToRad(this.camera3D.fov) / 2), + )); } + this.camera3D.aspect = ratio; } + this.width = width; + this.height = height; + updatePreSse(this, this.height, this.camera3D.fov); + if (this.camera3D.updateProjectionMatrix) { this.camera3D.updateProjectionMatrix(); this._viewMatrixNeedsUpdate = true; diff --git a/test/unit/camera.js b/test/unit/camera.js index 98201033a7..7c56e8232f 100644 --- a/test/unit/camera.js +++ b/test/unit/camera.js @@ -1,5 +1,5 @@ import assert from 'assert'; -import Camera from 'Renderer/Camera'; +import Camera, { CAMERA_TYPE } from 'Renderer/Camera'; import Coordinates from 'Core/Geographic/Coordinates'; function compareWithEpsilon(a, b, epsilon) { @@ -30,4 +30,24 @@ describe('camera', function () { assert.ok(compareWithEpsilon(resultCoordinates.latitude, coordinates.latitude, 10e-8)); assert.ok(compareWithEpsilon(resultCoordinates.altitude, coordinates.altitude, 10e-8)); }); + it('should correctly resize camera', function () { + const dimensions = { width: 78, height: 89 }; + + const cameraPerspective = new Camera( + 'EPSG:4978', + 100, 50, + ); + cameraPerspective.resize(dimensions.width, dimensions.height); + assert.equal(cameraPerspective.width, dimensions.width); + assert.equal(cameraPerspective.height, dimensions.height); + + const cameraOrthographic = new Camera( + 'EPSG:4978', + 100, 50, + { type: CAMERA_TYPE.ORTHOGRAPHIC }, + ); + cameraOrthographic.resize(dimensions.width, dimensions.height); + assert.equal(cameraOrthographic.width, dimensions.width); + assert.equal(cameraOrthographic.height, dimensions.height); + }); });