This repository has been archived by the owner on Mar 8, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 197
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
MAPSJS-2660: Move camera functions from MapViewUtils to CameraUtils. (#…
…2263) * MAPSJS-2660: Move camera functions from MapViewUtils to CameraUtils. - Deprecate calculateDepthFromClipDistance() and cameraToWorldDistance() - Move getCameraFrustumPlanes(), convertWorldToScreenSize(), convertScreenToWorldSize() and all functions related to fov and focalLength computations to CameraUtils. - Extract FovCalculation to a separate file. - Move MapView's limitFov code to CameraUtils' setVerticalFov(). Signed-off-by: Andres Mandado <andres.mandado-almajano@here.com> * MAPSJS-2660: Address review comments. Signed-off-by: Andres Mandado <andres.mandado-almajano@here.com>
- Loading branch information
1 parent
9e25396
commit c7f303e
Showing
11 changed files
with
252 additions
and
161 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
/* | ||
* Copyright (C) 2021 HERE Europe B.V. | ||
* Licensed under Apache 2.0, see full license in LICENSE | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
import * as THREE from "three"; | ||
|
||
import { MAX_FOV_RAD, MIN_FOV_RAD } from "./FovCalculation"; | ||
|
||
export namespace CameraUtils { | ||
/** | ||
* Computes a camera's vertical field of view for given focal length and viewport height. | ||
* @beta | ||
* | ||
* @param focalLength - Focal length in pixels (see {@link computeFocalLength}) | ||
* @param height - Viewport height in pixels. | ||
* @returns Vertical field of view in radians. | ||
*/ | ||
export function computeVerticalFov(focalLength: number, height: number): number { | ||
return 2 * Math.atan(height / 2 / focalLength); | ||
} | ||
|
||
/** | ||
* Computes a camera's horizontal field of view. | ||
* @beta | ||
* | ||
* @param camera | ||
* @returns Horizontal field of view in radians. | ||
*/ | ||
export function computeHorizontalFov(camera: THREE.PerspectiveCamera): number { | ||
const vFov = THREE.MathUtils.degToRad(camera.fov); | ||
return 2 * Math.atan(Math.tan(vFov / 2) * camera.aspect); | ||
} | ||
|
||
/** | ||
* Set a camera's horizontal field of view. | ||
* @internal | ||
* | ||
* @param camera | ||
* @param hFov - The horizontal field of view in radians. | ||
*/ | ||
export function setHorizontalFov(camera: THREE.PerspectiveCamera, hFov: number): void { | ||
camera.fov = THREE.MathUtils.radToDeg(2 * Math.atan(Math.tan(hFov / 2) / camera.aspect)); | ||
} | ||
|
||
/** | ||
* Sets a camera's vertical field of view. | ||
* @internal | ||
* | ||
* @param camera | ||
* @param fov - The vertical field of view in radians. | ||
*/ | ||
export function setVerticalFov(camera: THREE.PerspectiveCamera, fov: number): void { | ||
camera.fov = THREE.MathUtils.radToDeg(THREE.MathUtils.clamp(fov, MIN_FOV_RAD, MAX_FOV_RAD)); | ||
|
||
let hFov = computeHorizontalFov(camera); | ||
|
||
if (hFov > MAX_FOV_RAD || hFov < MIN_FOV_RAD) { | ||
hFov = THREE.MathUtils.clamp(hFov, MIN_FOV_RAD, MAX_FOV_RAD); | ||
setHorizontalFov(camera, hFov); | ||
} | ||
} | ||
|
||
/** | ||
* Computes a camera's focal length for a given viewport height. | ||
* @beta | ||
* | ||
* @param vFov - Vertical field of view in radians. | ||
* @param height - Viewport height in pixels. | ||
* @returns focal length in pixels. | ||
*/ | ||
export function computeFocalLength(vFov: number, height: number): number { | ||
return height / 2 / Math.tan(vFov / 2); | ||
} | ||
|
||
/** | ||
* Calculates object's screen size based on the focal length and it's camera distance. | ||
* @beta | ||
* | ||
* @param focalLength - Focal length in pixels (see {@link computeFocalLength}) | ||
* @param distance - Object distance in world space. | ||
* @param worldSize - Object size in world space. | ||
* @return object size in screen space. | ||
*/ | ||
export function convertWorldToScreenSize( | ||
focalLength: number, | ||
distance: number, | ||
worldSize: number | ||
): number { | ||
return (focalLength * worldSize) / distance; | ||
} | ||
|
||
/** | ||
* Calculates object's world size based on the focal length and it's camera distance. | ||
* @beta | ||
* | ||
* @param focalLength - Focal length in pixels (see {@link computeFocalLength}) | ||
* @param distance - Object distance in world space. | ||
* @param screenSize - Object size in screen space. | ||
* @return object size in world space. | ||
*/ | ||
export function convertScreenToWorldSize( | ||
focalLength: number, | ||
distance: number, | ||
screenSize: number | ||
): number { | ||
return (distance * screenSize) / focalLength; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
/* | ||
* Copyright (C) 2021 HERE Europe B.V. | ||
* Licensed under Apache 2.0, see full license in LICENSE | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
import * as THREE from "three"; | ||
|
||
/** | ||
* Specifies how the FOV (Field of View) should be calculated. | ||
*/ | ||
export interface FovCalculation { | ||
/** | ||
* How to interpret the [[fov]], can be either `fixed` or `dynamic`. | ||
* | ||
* `fixed` means that the FOV is fixed regardless of the [[viewportHeight]], such that shrinking | ||
* the height causes the map to shrink to keep the content in view. The benefit is that, | ||
* regardless of any resizes, the field of view is constant, which means there is no change in | ||
* the distortion of buildings near the edges. However the trade off is that the zoom level | ||
* changes, which means that the map will pull in new tiles, hence causing some flickering. | ||
* | ||
* `dynamic` means that the focal length is calculated based on the supplied [[fov]] and | ||
* [[viewportHeight]], this means that the map doesn't scale (the image is essentially cropped | ||
* but not shrunk) when the [[viewportHeight]] or [[viewportWidth]] is changed. The benefit is | ||
* that the zoom level is (currently) stable during resize, because the focal length is used, | ||
* however the tradeoff is that changing from a small to a big height will cause the fov to | ||
* change a lot, and thus introduce distortion. | ||
*/ | ||
type: "fixed" | "dynamic"; | ||
|
||
/** | ||
* Vertical field of view in degrees. | ||
* If [[type]] is `fixed` then the supplied [[fov]] is fixed regardless of | ||
* [[viewportHeight]] or [[viewportWidth]]. | ||
* | ||
* If [[type]] is `dynamic` then the supplied [[fov]] is applied to the | ||
* first frame, and the focal length calculated. Changes to the viewport | ||
* height no longer shrink the content because the field of view is updated | ||
* dynamically. | ||
*/ | ||
fov: number; | ||
} | ||
|
||
export const DEFAULT_FOV_CALCULATION: FovCalculation = { type: "dynamic", fov: 40 }; | ||
export const MIN_FOV_DEG = 10; | ||
export const MAX_FOV_DEG = 140; | ||
export const MIN_FOV_RAD = THREE.MathUtils.degToRad(MIN_FOV_DEG); | ||
export const MAX_FOV_RAD = THREE.MathUtils.degToRad(MAX_FOV_DEG); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.