123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285 |
- /**
- * @author zz85 / http://twitter.com/blurspline / http://www.lab4games.net/zz85/blog
- *
- * A general perpose camera, for setting FOV, Lens Focal Length,
- * and switching between perspective and orthographic views easily.
- * Use this only if you do not wish to manage
- * both a Orthographic and Perspective Camera
- *
- */
- THREE.CombinedCamera = function ( width, height, fov, near, far, orthoNear, orthoFar ) {
- THREE.Camera.call( this );
- this.fov = fov;
- this.far = far;
- this.near = near;
- this.left = - width / 2;
- this.right = width / 2;
- this.top = height / 2;
- this.bottom = - height / 2;
- this.aspect = width / height;
- this.zoom = 1;
- this.view = null;
- // 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.toPerspective();
- };
- THREE.CombinedCamera.prototype = Object.create( THREE.Camera.prototype );
- THREE.CombinedCamera.prototype.constructor = THREE.CombinedCamera;
- THREE.CombinedCamera.prototype.toPerspective = function () {
- // Switches to the Perspective Camera
- this.near = this.cameraP.near;
- this.far = this.cameraP.far;
- this.cameraP.aspect = this.aspect;
- this.cameraP.fov = this.fov / this.zoom ;
- this.cameraP.view = this.view;
- this.cameraP.updateProjectionMatrix();
- this.projectionMatrix = this.cameraP.projectionMatrix;
- this.inPerspectiveMode = true;
- this.inOrthographicMode = false;
- };
- THREE.CombinedCamera.prototype.toOrthographic = function () {
- // Switches to the Orthographic camera estimating viewport from Perspective
- var fov = this.fov;
- var aspect = this.cameraP.aspect;
- var near = this.cameraP.near;
- var far = this.cameraP.far;
- // The size that we set is the mid plane of the viewing frustum
- var hyperfocus = ( near + far ) / 2;
- var halfHeight = Math.tan( fov * Math.PI / 180 / 2 ) * hyperfocus;
- var halfWidth = halfHeight * aspect;
- halfHeight /= this.zoom;
- halfWidth /= this.zoom;
- this.cameraO.left = - halfWidth;
- this.cameraO.right = halfWidth;
- this.cameraO.top = halfHeight;
- this.cameraO.bottom = - halfHeight;
- this.cameraO.view = this.view;
- this.cameraO.updateProjectionMatrix();
- this.near = this.cameraO.near;
- this.far = this.cameraO.far;
- this.projectionMatrix = this.cameraO.projectionMatrix;
- this.inPerspectiveMode = false;
- this.inOrthographicMode = true;
- };
- THREE.CombinedCamera.prototype.copy = function ( source ) {
- THREE.Camera.prototype.copy.call( this, source );
- this.fov = source.fov;
- this.far = source.far;
- this.near = source.near;
- this.left = source.left;
- this.right = source.right;
- this.top = source.top;
- this.bottom = source.bottom;
- this.zoom = source.zoom;
- this.view = source.view === null ? null : Object.assign( {}, source.view );
- this.aspect = source.aspect;
- this.cameraO.copy( source.cameraO );
- this.cameraP.copy( source.cameraP );
- this.inOrthographicMode = source.inOrthographicMode;
- this.inPerspectiveMode = source.inPerspectiveMode;
- return this;
- };
- THREE.CombinedCamera.prototype.setViewOffset = function( fullWidth, fullHeight, x, y, width, height ) {
- this.view = {
- fullWidth: fullWidth,
- fullHeight: fullHeight,
- offsetX: x,
- offsetY: y,
- width: width,
- height: height
- };
- if ( this.inPerspectiveMode ) {
- this.aspect = fullWidth / fullHeight;
- this.toPerspective();
- } else {
- this.toOrthographic();
- }
- };
- THREE.CombinedCamera.prototype.clearViewOffset = function() {
- this.view = null;
- this.updateProjectionMatrix();
- };
- THREE.CombinedCamera.prototype.setSize = function( width, height ) {
- this.cameraP.aspect = width / height;
- this.left = - width / 2;
- this.right = width / 2;
- this.top = height / 2;
- this.bottom = - height / 2;
- };
- THREE.CombinedCamera.prototype.setFov = function( fov ) {
- this.fov = fov;
- if ( this.inPerspectiveMode ) {
- this.toPerspective();
- } else {
- this.toOrthographic();
- }
- };
- // For maintaining similar API with PerspectiveCamera
- THREE.CombinedCamera.prototype.updateProjectionMatrix = function() {
- if ( this.inPerspectiveMode ) {
- this.toPerspective();
- } else {
- this.toPerspective();
- this.toOrthographic();
- }
- };
- /*
- * Uses Focal Length (in mm) to estimate and set FOV
- * 35mm (full frame) 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, filmGauge ) {
- if ( filmGauge === undefined ) filmGauge = 35;
- var vExtentSlope = 0.5 * filmGauge /
- ( focalLength * Math.max( this.cameraP.aspect, 1 ) );
- var fov = THREE.Math.RAD2DEG * 2 * Math.atan( vExtentSlope );
- this.setFov( fov );
- return fov;
- };
- THREE.CombinedCamera.prototype.setZoom = function( zoom ) {
- this.zoom = zoom;
- if ( this.inPerspectiveMode ) {
- this.toPerspective();
- } else {
- this.toOrthographic();
- }
- };
- THREE.CombinedCamera.prototype.toFrontView = function() {
- this.rotation.x = 0;
- this.rotation.y = 0;
- this.rotation.z = 0;
- // should we be modifing the matrix instead?
- };
- THREE.CombinedCamera.prototype.toBackView = function() {
- this.rotation.x = 0;
- this.rotation.y = Math.PI;
- this.rotation.z = 0;
- };
- THREE.CombinedCamera.prototype.toLeftView = function() {
- this.rotation.x = 0;
- this.rotation.y = - Math.PI / 2;
- this.rotation.z = 0;
- };
- THREE.CombinedCamera.prototype.toRightView = function() {
- this.rotation.x = 0;
- this.rotation.y = Math.PI / 2;
- this.rotation.z = 0;
- };
- THREE.CombinedCamera.prototype.toTopView = function() {
- this.rotation.x = - Math.PI / 2;
- this.rotation.y = 0;
- this.rotation.z = 0;
- };
- THREE.CombinedCamera.prototype.toBottomView = function() {
- this.rotation.x = Math.PI / 2;
- this.rotation.y = 0;
- this.rotation.z = 0;
- };
|