/** * @author mr.doob / http://mrdoob.com/ * @author greggman / http://games.greggman.com/ * @author zz85 / http://www.lab4games.net/zz85/blog */ THREE.PerspectiveCamera = function ( fov, aspect, near, far ) { THREE.Camera.call( this ); this.fov = fov !== undefined ? fov : 50; this.aspect = aspect !== undefined ? aspect : 1; this.near = near !== undefined ? near : 0.1; this.far = far !== undefined ? far : 2000; this.updateProjectionMatrix(); }; THREE.PerspectiveCamera.prototype = new THREE.Camera(); THREE.PerspectiveCamera.prototype.constructor = THREE.PerspectiveCamera; /** * Uses Focal Length (in mm) to estimate and set FOV * 35mm (fullframe) camera is used if frame size is not specified; * Formula based on http://www.bobatkins.com/photography/technical/field_of_view.html */ THREE.PerspectiveCamera.prototype.setLens = function ( focalLength, frameSize ) { frameSize = frameSize !== undefined ? frameSize : 43.25; // 36x24mm this.fov = 2 * Math.atan( frameSize / ( focalLength * 2 ) ); this.fov = 180 / Math.PI * this.fov; this.updateProjectionMatrix(); } /** * Sets an offset in a larger frustum. This is useful for multi-window or * multi-monitor/multi-machine setups. * * 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 * * var w = 1920; * var h = 1080; * var fullWidth = w * 3; * var fullHeight = h * 2; * * --A-- * camera.setOffset( fullWidth, fullHeight, w * 0, h * 0, w, h ); * --B-- * camera.setOffset( fullWidth, fullHeight, w * 1, h * 0, w, h ); * --C-- * camera.setOffset( fullWidth, fullHeight, w * 2, h * 0, w, h ); * --D-- * camera.setOffset( fullWidth, fullHeight, w * 0, h * 1, w, h ); * --E-- * camera.setOffset( fullWidth, fullHeight, w * 1, h * 1, w, h ); * --F-- * camera.setOffset( fullWidth, fullHeight, w * 2, h * 1, w, h ); * * Note there is no reason monitors have to be the same size or in a grid. */ THREE.PerspectiveCamera.prototype.setViewOffset = function ( fullWidth, fullHeight, x, y, width, height ) { this.fullWidth = fullWidth; this.fullHeight = fullHeight; this.x = x; this.y = y; this.width = width; this.height = height; this.updateProjectionMatrix(); }; THREE.PerspectiveCamera.prototype.updateProjectionMatrix = function () { if ( this.fullWidth ) { var aspect = this.fullWidth / this.fullHeight; var top = Math.tan( this.fov * Math.PI / 360 ) * this.near; var bottom = -top; var left = aspect * bottom; var right = aspect * top; var width = Math.abs( right - left ); var height = Math.abs( top - bottom ); this.projectionMatrix = THREE.Matrix4.makeFrustum( left + this.x * width / this.fullWidth, left + ( this.x + this.width ) * width / this.fullWidth, top - ( this.y + this.height ) * height / this.fullHeight, top - this.y * height / this.fullHeight, this.near, this.far ); } else { this.projectionMatrix = THREE.Matrix4.makePerspective( this.fov, this.aspect, this.near, this.far ); } };