|
|
@@ -7,29 +7,121 @@ const _v3 = /*@__PURE__*/ new Vector3();
|
|
|
const _minTarget = /*@__PURE__*/ new Vector2();
|
|
|
const _maxTarget = /*@__PURE__*/ new Vector2();
|
|
|
|
|
|
-
|
|
|
+/**
|
|
|
+ * Camera that uses [perspective projection]{@link https://en.wikipedia.org/wiki/Perspective_(graphical)}.
|
|
|
+ *
|
|
|
+ * This projection mode is designed to mimic the way the human eye sees. It
|
|
|
+ * is the most common projection mode used for rendering a 3D scene.
|
|
|
+ *
|
|
|
+ * @augments Camera
|
|
|
+ */
|
|
|
class PerspectiveCamera extends Camera {
|
|
|
|
|
|
+ /**
|
|
|
+ * Constructs a new perspective camera.
|
|
|
+ *
|
|
|
+ * @param {number} [fov=50] - The vertical field of view.
|
|
|
+ * @param {number} [aspect=1] - The aspect ratio.
|
|
|
+ * @param {number} [near=0.1] - The camera's near plane.
|
|
|
+ * @param {number} [far=2000] - The camera's far plane.
|
|
|
+ */
|
|
|
constructor( fov = 50, aspect = 1, near = 0.1, far = 2000 ) {
|
|
|
|
|
|
super();
|
|
|
|
|
|
+ /**
|
|
|
+ * This flag can be used for type testing.
|
|
|
+ *
|
|
|
+ * @type {boolean}
|
|
|
+ * @readonly
|
|
|
+ * @default true
|
|
|
+ */
|
|
|
this.isPerspectiveCamera = true;
|
|
|
|
|
|
this.type = 'PerspectiveCamera';
|
|
|
|
|
|
+ /**
|
|
|
+ * The vertical field of view, from bottom to top of view,
|
|
|
+ * in degrees.
|
|
|
+ *
|
|
|
+ * @type {number}
|
|
|
+ * @default 50
|
|
|
+ */
|
|
|
this.fov = fov;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * The zoom factor of the camera.
|
|
|
+ *
|
|
|
+ * @type {number}
|
|
|
+ * @default 1
|
|
|
+ */
|
|
|
this.zoom = 1;
|
|
|
|
|
|
+ /**
|
|
|
+ * The camera's near plane. The valid range is greater than `0`
|
|
|
+ * and less than the current value of {@link PerspectiveCamera#far}.
|
|
|
+ *
|
|
|
+ * Note that, unlike for the {@link OrthographicCamera}, `0` is <em>not</em> a
|
|
|
+ * valid value for a perspective camera's near plane.
|
|
|
+ *
|
|
|
+ * @type {number}
|
|
|
+ * @default 0.1
|
|
|
+ */
|
|
|
this.near = near;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * The camera's far plane. Must be greater than the
|
|
|
+ * current value of {@link PerspectiveCamera#near}.
|
|
|
+ *
|
|
|
+ * @type {number}
|
|
|
+ * @default 2000
|
|
|
+ */
|
|
|
this.far = far;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Object distance used for stereoscopy and depth-of-field effects. This
|
|
|
+ * parameter does not influence the projection matrix unless a
|
|
|
+ * {@link StereoCamera} is being used.
|
|
|
+ *
|
|
|
+ * @type {number}
|
|
|
+ * @default 10
|
|
|
+ */
|
|
|
this.focus = 10;
|
|
|
|
|
|
+ /**
|
|
|
+ * The aspect ratio, usually the canvas width / canvas height.
|
|
|
+ *
|
|
|
+ * @type {number}
|
|
|
+ * @default 1
|
|
|
+ */
|
|
|
this.aspect = aspect;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Represents the frustum window specification. This property should not be edited
|
|
|
+ * directly but via {@link PerspectiveCamera#setViewOffset} and {@link PerspectiveCamera#clearViewOffset}.
|
|
|
+ *
|
|
|
+ * @type {?Object}
|
|
|
+ * @default null
|
|
|
+ */
|
|
|
this.view = null;
|
|
|
|
|
|
- this.filmGauge = 35; // width of the film (default in millimeters)
|
|
|
- this.filmOffset = 0; // horizontal film offset (same unit as gauge)
|
|
|
+ /**
|
|
|
+ * Film size used for the larger axis. Default is `35` (millimeters). This
|
|
|
+ * parameter does not influence the projection matrix unless {@link PerspectiveCamera#filmOffset}
|
|
|
+ * is set to a nonzero value.
|
|
|
+ *
|
|
|
+ * @type {number}
|
|
|
+ * @default 35
|
|
|
+ */
|
|
|
+ this.filmGauge = 35;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Horizontal off-center offset in the same unit as {@link PerspectiveCamera#filmGauge}.
|
|
|
+ *
|
|
|
+ * @type {number}
|
|
|
+ * @default 0
|
|
|
+ */
|
|
|
+ this.filmOffset = 0;
|
|
|
|
|
|
this.updateProjectionMatrix();
|
|
|
|
|
|
@@ -57,7 +149,7 @@ class PerspectiveCamera extends Camera {
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * Sets the FOV by focal length in respect to the current .filmGauge.
|
|
|
+ * Sets the FOV by focal length in respect to the current {@link PerspectiveCamera#filmGauge}.
|
|
|
*
|
|
|
* The default film gauge is 35, so that the focal length can be specified for
|
|
|
* a 35mm (full frame) camera.
|
|
|
@@ -75,9 +167,10 @@ class PerspectiveCamera extends Camera {
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * Calculates the focal length from the current .fov and .filmGauge.
|
|
|
+ * Returns the focal length from the current {@link PerspectiveCamera#fov} and
|
|
|
+ * {@link PerspectiveCamera#filmGauge}.
|
|
|
*
|
|
|
- * @returns {number}
|
|
|
+ * @return {number} The computed focal length.
|
|
|
*/
|
|
|
getFocalLength() {
|
|
|
|
|
|
@@ -87,6 +180,11 @@ class PerspectiveCamera extends Camera {
|
|
|
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Returns the current vertical field of view angle in degrees considering {@link PerspectiveCamera#zoom}.
|
|
|
+ *
|
|
|
+ * @return {number} The effective FOV.
|
|
|
+ */
|
|
|
getEffectiveFOV() {
|
|
|
|
|
|
return RAD2DEG * 2 * Math.atan(
|
|
|
@@ -94,6 +192,12 @@ class PerspectiveCamera extends Camera {
|
|
|
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Returns the width of the image on the film. If {@link PerspectiveCamera#aspect} is greater than or
|
|
|
+ * equal to one (landscape format), the result equals {@link PerspectiveCamera#filmGauge}.
|
|
|
+ *
|
|
|
+ * @return {number} The film width.
|
|
|
+ */
|
|
|
getFilmWidth() {
|
|
|
|
|
|
// film not completely covered in portrait format (aspect < 1)
|
|
|
@@ -101,6 +205,12 @@ class PerspectiveCamera extends Camera {
|
|
|
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Returns the height of the image on the film. If {@link PerspectiveCamera#aspect} is greater than or
|
|
|
+ * equal to one (landscape format), the result equals {@link PerspectiveCamera#filmGauge}.
|
|
|
+ *
|
|
|
+ * @return {number} The film width.
|
|
|
+ */
|
|
|
getFilmHeight() {
|
|
|
|
|
|
// film not completely covered in landscape format (aspect > 1)
|
|
|
@@ -110,11 +220,11 @@ class PerspectiveCamera extends Camera {
|
|
|
|
|
|
/**
|
|
|
* Computes the 2D bounds of the camera's viewable rectangle at a given distance along the viewing direction.
|
|
|
- * Sets minTarget and maxTarget to the coordinates of the lower-left and upper-right corners of the view rectangle.
|
|
|
+ * Sets `minTarget` and `maxTarget` to the coordinates of the lower-left and upper-right corners of the view rectangle.
|
|
|
*
|
|
|
- * @param {number} distance
|
|
|
- * @param {Vector2} minTarget
|
|
|
- * @param {Vector2} maxTarget
|
|
|
+ * @param {number} distance - The viewing distance.
|
|
|
+ * @param {Vector2} minTarget - The lower-left corner of the view rectangle is written into this vector.
|
|
|
+ * @param {Vector2} maxTarget - The upper-right corner of the view rectangle is written into this vector.
|
|
|
*/
|
|
|
getViewBounds( distance, minTarget, maxTarget ) {
|
|
|
|
|
|
@@ -131,9 +241,9 @@ class PerspectiveCamera extends Camera {
|
|
|
/**
|
|
|
* Computes the width and height of the camera's viewable rectangle at a given distance along the viewing direction.
|
|
|
*
|
|
|
- * @param {number} distance
|
|
|
- * @param {Vector2} target - Vector2 target used to store result where x is width and y is height.
|
|
|
- * @returns {Vector2}
|
|
|
+ * @param {number} distance - The viewing distance.
|
|
|
+ * @param {Vector2} target - The target vector that is used to store result where x is width and y is height.
|
|
|
+ * @returns {Vector2} The view size.
|
|
|
*/
|
|
|
getViewSize( distance, target ) {
|
|
|
|
|
|
@@ -149,41 +259,42 @@ class PerspectiveCamera extends Camera {
|
|
|
*
|
|
|
* For example, if you have 3x2 monitors and each monitor is 1920x1080 and
|
|
|
* the monitors are in grid like this
|
|
|
- *
|
|
|
+ *```
|
|
|
* +---+---+---+
|
|
|
* | A | B | C |
|
|
|
* +---+---+---+
|
|
|
* | D | E | F |
|
|
|
* +---+---+---+
|
|
|
+ *```
|
|
|
+ * then for each monitor you would call it like this:
|
|
|
+ *```js
|
|
|
+ * const w = 1920;
|
|
|
+ * const h = 1080;
|
|
|
+ * const fullWidth = w * 3;
|
|
|
+ * const fullHeight = h * 2;
|
|
|
*
|
|
|
- * then for each monitor you would call it like this
|
|
|
+ * // --A--
|
|
|
+ * camera.setViewOffset( fullWidth, fullHeight, w * 0, h * 0, w, h );
|
|
|
+ * // --B--
|
|
|
+ * camera.setViewOffset( fullWidth, fullHeight, w * 1, h * 0, w, h );
|
|
|
+ * // --C--
|
|
|
+ * camera.setViewOffset( fullWidth, fullHeight, w * 2, h * 0, w, h );
|
|
|
+ * // --D--
|
|
|
+ * camera.setViewOffset( fullWidth, fullHeight, w * 0, h * 1, w, h );
|
|
|
+ * // --E--
|
|
|
+ * camera.setViewOffset( fullWidth, fullHeight, w * 1, h * 1, w, h );
|
|
|
+ * // --F--
|
|
|
+ * camera.setViewOffset( fullWidth, fullHeight, w * 2, h * 1, w, h );
|
|
|
+ * ```
|
|
|
*
|
|
|
- * const w = 1920;
|
|
|
- * const h = 1080;
|
|
|
- * const fullWidth = w * 3;
|
|
|
- * const fullHeight = h * 2;
|
|
|
+ * Note there is no reason monitors have to be the same size or in a grid.
|
|
|
*
|
|
|
- * --A--
|
|
|
- * camera.setViewOffset( fullWidth, fullHeight, w * 0, h * 0, w, h );
|
|
|
- * --B--
|
|
|
- * camera.setViewOffset( fullWidth, fullHeight, w * 1, h * 0, w, h );
|
|
|
- * --C--
|
|
|
- * camera.setViewOffset( fullWidth, fullHeight, w * 2, h * 0, w, h );
|
|
|
- * --D--
|
|
|
- * camera.setViewOffset( fullWidth, fullHeight, w * 0, h * 1, w, h );
|
|
|
- * --E--
|
|
|
- * camera.setViewOffset( fullWidth, fullHeight, w * 1, h * 1, w, h );
|
|
|
- * --F--
|
|
|
- * camera.setViewOffset( fullWidth, fullHeight, w * 2, h * 1, w, h );
|
|
|
- *
|
|
|
- * Note there is no reason monitors have to be the same size or in a grid.
|
|
|
- *
|
|
|
- * @param {number} fullWidth
|
|
|
- * @param {number} fullHeight
|
|
|
- * @param {number} x
|
|
|
- * @param {number} y
|
|
|
- * @param {number} width
|
|
|
- * @param {number} height
|
|
|
+ * @param {number} fullWidth - The full width of multiview setup.
|
|
|
+ * @param {number} fullHeight - The full height of multiview setup.
|
|
|
+ * @param {number} x - The horizontal offset of the subcamera.
|
|
|
+ * @param {number} y - The vertical offset of the subcamera.
|
|
|
+ * @param {number} width - The width of subcamera.
|
|
|
+ * @param {number} height - The height of subcamera.
|
|
|
*/
|
|
|
setViewOffset( fullWidth, fullHeight, x, y, width, height ) {
|
|
|
|
|
|
@@ -215,6 +326,9 @@ class PerspectiveCamera extends Camera {
|
|
|
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Removes the view offset from the projection matrix.
|
|
|
+ */
|
|
|
clearViewOffset() {
|
|
|
|
|
|
if ( this.view !== null ) {
|
|
|
@@ -227,6 +341,10 @@ class PerspectiveCamera extends Camera {
|
|
|
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Updates the camera's projection matrix. Must be called after any change of
|
|
|
+ * camera properties.
|
|
|
+ */
|
|
|
updateProjectionMatrix() {
|
|
|
|
|
|
const near = this.near;
|