/* * @author zz85 / http://twitter.com/blurspline / http://www.lab4games.net/zz85/blog * * A handy general perpose camera, for setting FOV, Lens Focal Length, * and switching between perspective and orthographic views easily. * */ THREE.CombinedCamera = function ( width, height, fov, near, far, orthonear, orthofar ) { THREE.Camera.call( this ); this.fov = fov; this.left = -width / 2; this.right = width / 2 this.top = height / 2; this.bottom = -height / 2; // We could also handle the projectionMatrix internally, but just wanted to test nested camera objects this.cameraO = new THREE.OrthographicCamera( width / - 2, width / 2, height / 2, height / - 2, orthonear, orthofar ); this.cameraP = new THREE.PerspectiveCamera( fov, width/height, near, far ); this.zoom = 1; this.toPerspective(); var aspect = width/height; }; THREE.CombinedCamera.prototype = new THREE.Camera(); THREE.CombinedCamera.prototype.constructor = THREE.CoolCamera; THREE.CombinedCamera.prototype.toPerspective = function () { this.near = this.cameraP.near; this.far = this.cameraP.far; this.cameraP.fov = this.fov / this.zoom ; this.cameraP.updateProjectionMatrix(); this.projectionMatrix = this.cameraP.projectionMatrix; this.inPersepectiveMode = true; this.inOrthographicMode = false; }; THREE.CombinedCamera.prototype.toOrthographic = function () { // Orthographic from Perspective var fov = this.fov; var aspect = this.cameraP.aspect; var near = this.cameraP.near; var far = this.cameraP.far; // Just pretend we want the mid plane of the viewing frustum var hyperfocus = ( near + far ) / 2; var halfHeight = Math.tan( fov / 2 ) * hyperfocus; var planeHeight = 2 * halfHeight; var planeWidth = planeHeight * aspect; var halfWidth = planeWidth / 2; halfHeight /= this.zoom; halfWidth /= this.zoom; this.cameraO.left = -halfWidth; this.cameraO.right = halfWidth; this.cameraO.top = halfHeight; this.cameraO.bottom = -halfHeight; // this.cameraO.left = -farHalfWidth; // this.cameraO.right = farHalfWidth; // this.cameraO.top = farHalfHeight; // this.cameraO.bottom = -farHalfHeight; // this.cameraO.left = this.left / this.zoom; // this.cameraO.right = this.right / this.zoom; // this.cameraO.top = this.top / this.zoom; // this.cameraO.bottom = this.bottom / this.zoom; this.cameraO.updateProjectionMatrix(); this.near = this.cameraO.near; this.far = this.cameraO.far; this.projectionMatrix = this.cameraO.projectionMatrix; this.inPersepectiveMode = false; this.inOrthographicMode = true; }; THREE.CombinedCamera.prototype.setFov = function(fov) { this.fov = fov; if (this.inPersepectiveMode) { this.toPerspective(); } else { this.toOrthographic(); } }; /* * 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.CombinedCamera.prototype.setLens = function(focalLength, framesize) { if (!framesize) framesize = 43.25; // 36x24mm var fov = 2 * Math.atan( framesize / (focalLength * 2)); fov = 180 / Math.PI * fov; this.setFov(fov); return fov; }; THREE.CombinedCamera.prototype.setZoom = function(zoom) { this.zoom = zoom; if (this.inPersepectiveMode) { this.toPerspective(); } else { this.toOrthographic(); } }; THREE.CombinedCamera.prototype.toFrontView = function() { this.rotation.x = 0; this.rotation.y = 0; this.rotation.z = 0; //TODO: Better way to disable camera.lookAt()? this.rotationAutoUpdate = false; }; THREE.CombinedCamera.prototype.toBackView = function() { this.rotation.x = 0; this.rotation.y = Math.PI; this.rotation.z = 0; this.rotationAutoUpdate = false; }; THREE.CombinedCamera.prototype.toLeftView = function() { this.rotation.x = 0; this.rotation.y = - Math.PI / 2; this.rotation.z = 0; this.rotationAutoUpdate = false; }; THREE.CombinedCamera.prototype.toRightView = function() { this.rotation.x = 0; this.rotation.y = Math.PI / 2; this.rotation.z = 0; this.rotationAutoUpdate = false; }; THREE.CombinedCamera.prototype.toTopView = function() { this.rotation.x = - Math.PI / 2; this.rotation.y = 0; this.rotation.z = 0; this.rotationAutoUpdate = false; }; THREE.CombinedCamera.prototype.toBottomView = function() { this.rotation.x = Math.PI / 2; this.rotation.y = 0; this.rotation.z = 0; this.rotationAutoUpdate = false; };