initial commit
This commit is contained in:
24
lib/cameras/ArrayCamera.js
Normal file
24
lib/cameras/ArrayCamera.js
Normal file
@ -0,0 +1,24 @@
|
||||
/**
|
||||
* @author mrdoob / http://mrdoob.com/
|
||||
*/
|
||||
|
||||
import { PerspectiveCamera } from './PerspectiveCamera.js';
|
||||
|
||||
function ArrayCamera( array ) {
|
||||
|
||||
PerspectiveCamera.call( this );
|
||||
|
||||
this.cameras = array || [];
|
||||
|
||||
}
|
||||
|
||||
ArrayCamera.prototype = Object.assign( Object.create( PerspectiveCamera.prototype ), {
|
||||
|
||||
constructor: ArrayCamera,
|
||||
|
||||
isArrayCamera: true
|
||||
|
||||
} );
|
||||
|
||||
|
||||
export { ArrayCamera };
|
76
lib/cameras/Camera.js
Normal file
76
lib/cameras/Camera.js
Normal file
@ -0,0 +1,76 @@
|
||||
/**
|
||||
* @author mrdoob / http://mrdoob.com/
|
||||
* @author mikael emtinger / http://gomo.se/
|
||||
* @author WestLangley / http://github.com/WestLangley
|
||||
*/
|
||||
|
||||
import { Matrix4 } from '../math/Matrix4.js';
|
||||
import { Object3D } from '../core/Object3D.js';
|
||||
import { Vector3 } from '../math/Vector3.js';
|
||||
|
||||
function Camera() {
|
||||
|
||||
Object3D.call( this );
|
||||
|
||||
this.type = 'Camera';
|
||||
|
||||
this.matrixWorldInverse = new Matrix4();
|
||||
|
||||
this.projectionMatrix = new Matrix4();
|
||||
this.projectionMatrixInverse = new Matrix4();
|
||||
|
||||
}
|
||||
|
||||
Camera.prototype = Object.assign( Object.create( Object3D.prototype ), {
|
||||
|
||||
constructor: Camera,
|
||||
|
||||
isCamera: true,
|
||||
|
||||
copy: function ( source, recursive ) {
|
||||
|
||||
Object3D.prototype.copy.call( this, source, recursive );
|
||||
|
||||
this.matrixWorldInverse.copy( source.matrixWorldInverse );
|
||||
|
||||
this.projectionMatrix.copy( source.projectionMatrix );
|
||||
this.projectionMatrixInverse.copy( source.projectionMatrixInverse );
|
||||
|
||||
return this;
|
||||
|
||||
},
|
||||
|
||||
getWorldDirection: function ( target ) {
|
||||
|
||||
if ( target === undefined ) {
|
||||
|
||||
console.warn( 'THREE.Camera: .getWorldDirection() target is now required' );
|
||||
target = new Vector3();
|
||||
|
||||
}
|
||||
|
||||
this.updateMatrixWorld( true );
|
||||
|
||||
var e = this.matrixWorld.elements;
|
||||
|
||||
return target.set( - e[ 8 ], - e[ 9 ], - e[ 10 ] ).normalize();
|
||||
|
||||
},
|
||||
|
||||
updateMatrixWorld: function ( force ) {
|
||||
|
||||
Object3D.prototype.updateMatrixWorld.call( this, force );
|
||||
|
||||
this.matrixWorldInverse.getInverse( this.matrixWorld );
|
||||
|
||||
},
|
||||
|
||||
clone: function () {
|
||||
|
||||
return new this.constructor().copy( this );
|
||||
|
||||
}
|
||||
|
||||
} );
|
||||
|
||||
export { Camera };
|
113
lib/cameras/CubeCamera.js
Normal file
113
lib/cameras/CubeCamera.js
Normal file
@ -0,0 +1,113 @@
|
||||
import { Object3D } from '../core/Object3D.js';
|
||||
import { WebGLRenderTargetCube } from '../renderers/WebGLRenderTargetCube.js';
|
||||
import { LinearFilter, RGBFormat } from '../constants.js';
|
||||
import { Vector3 } from '../math/Vector3.js';
|
||||
import { PerspectiveCamera } from './PerspectiveCamera.js';
|
||||
|
||||
/**
|
||||
* Camera for rendering cube maps
|
||||
* - renders scene into axis-aligned cube
|
||||
*
|
||||
* @author alteredq / http://alteredqualia.com/
|
||||
*/
|
||||
|
||||
function CubeCamera( near, far, cubeResolution, options ) {
|
||||
|
||||
Object3D.call( this );
|
||||
|
||||
this.type = 'CubeCamera';
|
||||
|
||||
var fov = 90, aspect = 1;
|
||||
|
||||
var cameraPX = new PerspectiveCamera( fov, aspect, near, far );
|
||||
cameraPX.up.set( 0, - 1, 0 );
|
||||
cameraPX.lookAt( new Vector3( 1, 0, 0 ) );
|
||||
this.add( cameraPX );
|
||||
|
||||
var cameraNX = new PerspectiveCamera( fov, aspect, near, far );
|
||||
cameraNX.up.set( 0, - 1, 0 );
|
||||
cameraNX.lookAt( new Vector3( - 1, 0, 0 ) );
|
||||
this.add( cameraNX );
|
||||
|
||||
var cameraPY = new PerspectiveCamera( fov, aspect, near, far );
|
||||
cameraPY.up.set( 0, 0, 1 );
|
||||
cameraPY.lookAt( new Vector3( 0, 1, 0 ) );
|
||||
this.add( cameraPY );
|
||||
|
||||
var cameraNY = new PerspectiveCamera( fov, aspect, near, far );
|
||||
cameraNY.up.set( 0, 0, - 1 );
|
||||
cameraNY.lookAt( new Vector3( 0, - 1, 0 ) );
|
||||
this.add( cameraNY );
|
||||
|
||||
var cameraPZ = new PerspectiveCamera( fov, aspect, near, far );
|
||||
cameraPZ.up.set( 0, - 1, 0 );
|
||||
cameraPZ.lookAt( new Vector3( 0, 0, 1 ) );
|
||||
this.add( cameraPZ );
|
||||
|
||||
var cameraNZ = new PerspectiveCamera( fov, aspect, near, far );
|
||||
cameraNZ.up.set( 0, - 1, 0 );
|
||||
cameraNZ.lookAt( new Vector3( 0, 0, - 1 ) );
|
||||
this.add( cameraNZ );
|
||||
|
||||
options = options || { format: RGBFormat, magFilter: LinearFilter, minFilter: LinearFilter };
|
||||
|
||||
this.renderTarget = new WebGLRenderTargetCube( cubeResolution, cubeResolution, options );
|
||||
this.renderTarget.texture.name = "CubeCamera";
|
||||
|
||||
this.update = function ( renderer, scene ) {
|
||||
|
||||
if ( this.parent === null ) this.updateMatrixWorld();
|
||||
|
||||
var renderTarget = this.renderTarget;
|
||||
var generateMipmaps = renderTarget.texture.generateMipmaps;
|
||||
|
||||
renderTarget.texture.generateMipmaps = false;
|
||||
|
||||
renderTarget.activeCubeFace = 0;
|
||||
renderer.render( scene, cameraPX, renderTarget );
|
||||
|
||||
renderTarget.activeCubeFace = 1;
|
||||
renderer.render( scene, cameraNX, renderTarget );
|
||||
|
||||
renderTarget.activeCubeFace = 2;
|
||||
renderer.render( scene, cameraPY, renderTarget );
|
||||
|
||||
renderTarget.activeCubeFace = 3;
|
||||
renderer.render( scene, cameraNY, renderTarget );
|
||||
|
||||
renderTarget.activeCubeFace = 4;
|
||||
renderer.render( scene, cameraPZ, renderTarget );
|
||||
|
||||
renderTarget.texture.generateMipmaps = generateMipmaps;
|
||||
|
||||
renderTarget.activeCubeFace = 5;
|
||||
renderer.render( scene, cameraNZ, renderTarget );
|
||||
|
||||
renderer.setRenderTarget( null );
|
||||
|
||||
};
|
||||
|
||||
this.clear = function ( renderer, color, depth, stencil ) {
|
||||
|
||||
var renderTarget = this.renderTarget;
|
||||
|
||||
for ( var i = 0; i < 6; i ++ ) {
|
||||
|
||||
renderTarget.activeCubeFace = i;
|
||||
renderer.setRenderTarget( renderTarget );
|
||||
|
||||
renderer.clear( color, depth, stencil );
|
||||
|
||||
}
|
||||
|
||||
renderer.setRenderTarget( null );
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
CubeCamera.prototype = Object.create( Object3D.prototype );
|
||||
CubeCamera.prototype.constructor = CubeCamera;
|
||||
|
||||
|
||||
export { CubeCamera };
|
147
lib/cameras/OrthographicCamera.js
Executable file
147
lib/cameras/OrthographicCamera.js
Executable file
@ -0,0 +1,147 @@
|
||||
import { Camera } from './Camera.js';
|
||||
import { Object3D } from '../core/Object3D.js';
|
||||
|
||||
/**
|
||||
* @author alteredq / http://alteredqualia.com/
|
||||
* @author arose / http://github.com/arose
|
||||
*/
|
||||
|
||||
function OrthographicCamera( left, right, top, bottom, near, far ) {
|
||||
|
||||
Camera.call( this );
|
||||
|
||||
this.type = 'OrthographicCamera';
|
||||
|
||||
this.zoom = 1;
|
||||
this.view = null;
|
||||
|
||||
this.left = ( left !== undefined ) ? left : - 1;
|
||||
this.right = ( right !== undefined ) ? right : 1;
|
||||
this.top = ( top !== undefined ) ? top : 1;
|
||||
this.bottom = ( bottom !== undefined ) ? bottom : - 1;
|
||||
|
||||
this.near = ( near !== undefined ) ? near : 0.1;
|
||||
this.far = ( far !== undefined ) ? far : 2000;
|
||||
|
||||
this.updateProjectionMatrix();
|
||||
|
||||
}
|
||||
|
||||
OrthographicCamera.prototype = Object.assign( Object.create( Camera.prototype ), {
|
||||
|
||||
constructor: OrthographicCamera,
|
||||
|
||||
isOrthographicCamera: true,
|
||||
|
||||
copy: function ( source, recursive ) {
|
||||
|
||||
Camera.prototype.copy.call( this, source, recursive );
|
||||
|
||||
this.left = source.left;
|
||||
this.right = source.right;
|
||||
this.top = source.top;
|
||||
this.bottom = source.bottom;
|
||||
this.near = source.near;
|
||||
this.far = source.far;
|
||||
|
||||
this.zoom = source.zoom;
|
||||
this.view = source.view === null ? null : Object.assign( {}, source.view );
|
||||
|
||||
return this;
|
||||
|
||||
},
|
||||
|
||||
setViewOffset: function ( fullWidth, fullHeight, x, y, width, height ) {
|
||||
|
||||
if ( this.view === null ) {
|
||||
|
||||
this.view = {
|
||||
enabled: true,
|
||||
fullWidth: 1,
|
||||
fullHeight: 1,
|
||||
offsetX: 0,
|
||||
offsetY: 0,
|
||||
width: 1,
|
||||
height: 1
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
this.view.enabled = true;
|
||||
this.view.fullWidth = fullWidth;
|
||||
this.view.fullHeight = fullHeight;
|
||||
this.view.offsetX = x;
|
||||
this.view.offsetY = y;
|
||||
this.view.width = width;
|
||||
this.view.height = height;
|
||||
|
||||
this.updateProjectionMatrix();
|
||||
|
||||
},
|
||||
|
||||
clearViewOffset: function () {
|
||||
|
||||
if ( this.view !== null ) {
|
||||
|
||||
this.view.enabled = false;
|
||||
|
||||
}
|
||||
|
||||
this.updateProjectionMatrix();
|
||||
|
||||
},
|
||||
|
||||
updateProjectionMatrix: function () {
|
||||
|
||||
var dx = ( this.right - this.left ) / ( 2 * this.zoom );
|
||||
var dy = ( this.top - this.bottom ) / ( 2 * this.zoom );
|
||||
var cx = ( this.right + this.left ) / 2;
|
||||
var cy = ( this.top + this.bottom ) / 2;
|
||||
|
||||
var left = cx - dx;
|
||||
var right = cx + dx;
|
||||
var top = cy + dy;
|
||||
var bottom = cy - dy;
|
||||
|
||||
if ( this.view !== null && this.view.enabled ) {
|
||||
|
||||
var zoomW = this.zoom / ( this.view.width / this.view.fullWidth );
|
||||
var zoomH = this.zoom / ( this.view.height / this.view.fullHeight );
|
||||
var scaleW = ( this.right - this.left ) / this.view.width;
|
||||
var scaleH = ( this.top - this.bottom ) / this.view.height;
|
||||
|
||||
left += scaleW * ( this.view.offsetX / zoomW );
|
||||
right = left + scaleW * ( this.view.width / zoomW );
|
||||
top -= scaleH * ( this.view.offsetY / zoomH );
|
||||
bottom = top - scaleH * ( this.view.height / zoomH );
|
||||
|
||||
}
|
||||
|
||||
this.projectionMatrix.makeOrthographic( left, right, top, bottom, this.near, this.far );
|
||||
|
||||
this.projectionMatrixInverse.getInverse( this.projectionMatrix );
|
||||
|
||||
},
|
||||
|
||||
toJSON: function ( meta ) {
|
||||
|
||||
var data = Object3D.prototype.toJSON.call( this, meta );
|
||||
|
||||
data.object.zoom = this.zoom;
|
||||
data.object.left = this.left;
|
||||
data.object.right = this.right;
|
||||
data.object.top = this.top;
|
||||
data.object.bottom = this.bottom;
|
||||
data.object.near = this.near;
|
||||
data.object.far = this.far;
|
||||
|
||||
if ( this.view !== null ) data.object.view = Object.assign( {}, this.view );
|
||||
|
||||
return data;
|
||||
|
||||
}
|
||||
|
||||
} );
|
||||
|
||||
|
||||
export { OrthographicCamera };
|
244
lib/cameras/PerspectiveCamera.js
Executable file
244
lib/cameras/PerspectiveCamera.js
Executable file
@ -0,0 +1,244 @@
|
||||
import { Camera } from './Camera.js';
|
||||
import { Object3D } from '../core/Object3D.js';
|
||||
import { _Math } from '../math/Math.js';
|
||||
|
||||
/**
|
||||
* @author mrdoob / http://mrdoob.com/
|
||||
* @author greggman / http://games.greggman.com/
|
||||
* @author zz85 / http://www.lab4games.net/zz85/blog
|
||||
* @author tschw
|
||||
*/
|
||||
|
||||
function PerspectiveCamera( fov, aspect, near, far ) {
|
||||
|
||||
Camera.call( this );
|
||||
|
||||
this.type = 'PerspectiveCamera';
|
||||
|
||||
this.fov = fov !== undefined ? fov : 50;
|
||||
this.zoom = 1;
|
||||
|
||||
this.near = near !== undefined ? near : 0.1;
|
||||
this.far = far !== undefined ? far : 2000;
|
||||
this.focus = 10;
|
||||
|
||||
this.aspect = aspect !== undefined ? aspect : 1;
|
||||
this.view = null;
|
||||
|
||||
this.filmGauge = 35; // width of the film (default in millimeters)
|
||||
this.filmOffset = 0; // horizontal film offset (same unit as gauge)
|
||||
|
||||
this.updateProjectionMatrix();
|
||||
|
||||
}
|
||||
|
||||
PerspectiveCamera.prototype = Object.assign( Object.create( Camera.prototype ), {
|
||||
|
||||
constructor: PerspectiveCamera,
|
||||
|
||||
isPerspectiveCamera: true,
|
||||
|
||||
copy: function ( source, recursive ) {
|
||||
|
||||
Camera.prototype.copy.call( this, source, recursive );
|
||||
|
||||
this.fov = source.fov;
|
||||
this.zoom = source.zoom;
|
||||
|
||||
this.near = source.near;
|
||||
this.far = source.far;
|
||||
this.focus = source.focus;
|
||||
|
||||
this.aspect = source.aspect;
|
||||
this.view = source.view === null ? null : Object.assign( {}, source.view );
|
||||
|
||||
this.filmGauge = source.filmGauge;
|
||||
this.filmOffset = source.filmOffset;
|
||||
|
||||
return this;
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets the FOV by focal length in respect to the current .filmGauge.
|
||||
*
|
||||
* The default film gauge is 35, so that the focal length can be specified for
|
||||
* a 35mm (full frame) camera.
|
||||
*
|
||||
* Values for focal length and film gauge must have the same unit.
|
||||
*/
|
||||
setFocalLength: function ( focalLength ) {
|
||||
|
||||
// see http://www.bobatkins.com/photography/technical/field_of_view.html
|
||||
var vExtentSlope = 0.5 * this.getFilmHeight() / focalLength;
|
||||
|
||||
this.fov = _Math.RAD2DEG * 2 * Math.atan( vExtentSlope );
|
||||
this.updateProjectionMatrix();
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Calculates the focal length from the current .fov and .filmGauge.
|
||||
*/
|
||||
getFocalLength: function () {
|
||||
|
||||
var vExtentSlope = Math.tan( _Math.DEG2RAD * 0.5 * this.fov );
|
||||
|
||||
return 0.5 * this.getFilmHeight() / vExtentSlope;
|
||||
|
||||
},
|
||||
|
||||
getEffectiveFOV: function () {
|
||||
|
||||
return _Math.RAD2DEG * 2 * Math.atan(
|
||||
Math.tan( _Math.DEG2RAD * 0.5 * this.fov ) / this.zoom );
|
||||
|
||||
},
|
||||
|
||||
getFilmWidth: function () {
|
||||
|
||||
// film not completely covered in portrait format (aspect < 1)
|
||||
return this.filmGauge * Math.min( this.aspect, 1 );
|
||||
|
||||
},
|
||||
|
||||
getFilmHeight: function () {
|
||||
|
||||
// film not completely covered in landscape format (aspect > 1)
|
||||
return this.filmGauge / Math.max( this.aspect, 1 );
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
setViewOffset: function ( fullWidth, fullHeight, x, y, width, height ) {
|
||||
|
||||
this.aspect = fullWidth / fullHeight;
|
||||
|
||||
if ( this.view === null ) {
|
||||
|
||||
this.view = {
|
||||
enabled: true,
|
||||
fullWidth: 1,
|
||||
fullHeight: 1,
|
||||
offsetX: 0,
|
||||
offsetY: 0,
|
||||
width: 1,
|
||||
height: 1
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
this.view.enabled = true;
|
||||
this.view.fullWidth = fullWidth;
|
||||
this.view.fullHeight = fullHeight;
|
||||
this.view.offsetX = x;
|
||||
this.view.offsetY = y;
|
||||
this.view.width = width;
|
||||
this.view.height = height;
|
||||
|
||||
this.updateProjectionMatrix();
|
||||
|
||||
},
|
||||
|
||||
clearViewOffset: function () {
|
||||
|
||||
if ( this.view !== null ) {
|
||||
|
||||
this.view.enabled = false;
|
||||
|
||||
}
|
||||
|
||||
this.updateProjectionMatrix();
|
||||
|
||||
},
|
||||
|
||||
updateProjectionMatrix: function () {
|
||||
|
||||
var near = this.near,
|
||||
top = near * Math.tan( _Math.DEG2RAD * 0.5 * this.fov ) / this.zoom,
|
||||
height = 2 * top,
|
||||
width = this.aspect * height,
|
||||
left = - 0.5 * width,
|
||||
view = this.view;
|
||||
|
||||
if ( this.view !== null && this.view.enabled ) {
|
||||
|
||||
var fullWidth = view.fullWidth,
|
||||
fullHeight = view.fullHeight;
|
||||
|
||||
left += view.offsetX * width / fullWidth;
|
||||
top -= view.offsetY * height / fullHeight;
|
||||
width *= view.width / fullWidth;
|
||||
height *= view.height / fullHeight;
|
||||
|
||||
}
|
||||
|
||||
var skew = this.filmOffset;
|
||||
if ( skew !== 0 ) left += near * skew / this.getFilmWidth();
|
||||
|
||||
this.projectionMatrix.makePerspective( left, left + width, top, top - height, near, this.far );
|
||||
|
||||
this.projectionMatrixInverse.getInverse( this.projectionMatrix );
|
||||
|
||||
},
|
||||
|
||||
toJSON: function ( meta ) {
|
||||
|
||||
var data = Object3D.prototype.toJSON.call( this, meta );
|
||||
|
||||
data.object.fov = this.fov;
|
||||
data.object.zoom = this.zoom;
|
||||
|
||||
data.object.near = this.near;
|
||||
data.object.far = this.far;
|
||||
data.object.focus = this.focus;
|
||||
|
||||
data.object.aspect = this.aspect;
|
||||
|
||||
if ( this.view !== null ) data.object.view = Object.assign( {}, this.view );
|
||||
|
||||
data.object.filmGauge = this.filmGauge;
|
||||
data.object.filmOffset = this.filmOffset;
|
||||
|
||||
return data;
|
||||
|
||||
}
|
||||
|
||||
} );
|
||||
|
||||
|
||||
export { PerspectiveCamera };
|
98
lib/cameras/StereoCamera.js
Normal file
98
lib/cameras/StereoCamera.js
Normal file
@ -0,0 +1,98 @@
|
||||
import { Matrix4 } from '../math/Matrix4.js';
|
||||
import { _Math } from '../math/Math.js';
|
||||
import { PerspectiveCamera } from './PerspectiveCamera.js';
|
||||
|
||||
/**
|
||||
* @author mrdoob / http://mrdoob.com/
|
||||
*/
|
||||
|
||||
function StereoCamera() {
|
||||
|
||||
this.type = 'StereoCamera';
|
||||
|
||||
this.aspect = 1;
|
||||
|
||||
this.eyeSep = 0.064;
|
||||
|
||||
this.cameraL = new PerspectiveCamera();
|
||||
this.cameraL.layers.enable( 1 );
|
||||
this.cameraL.matrixAutoUpdate = false;
|
||||
|
||||
this.cameraR = new PerspectiveCamera();
|
||||
this.cameraR.layers.enable( 2 );
|
||||
this.cameraR.matrixAutoUpdate = false;
|
||||
|
||||
}
|
||||
|
||||
Object.assign( StereoCamera.prototype, {
|
||||
|
||||
update: ( function () {
|
||||
|
||||
var instance, focus, fov, aspect, near, far, zoom, eyeSep;
|
||||
|
||||
var eyeRight = new Matrix4();
|
||||
var eyeLeft = new Matrix4();
|
||||
|
||||
return function update( camera ) {
|
||||
|
||||
var needsUpdate = instance !== this || focus !== camera.focus || fov !== camera.fov ||
|
||||
aspect !== camera.aspect * this.aspect || near !== camera.near ||
|
||||
far !== camera.far || zoom !== camera.zoom || eyeSep !== this.eyeSep;
|
||||
|
||||
if ( needsUpdate ) {
|
||||
|
||||
instance = this;
|
||||
focus = camera.focus;
|
||||
fov = camera.fov;
|
||||
aspect = camera.aspect * this.aspect;
|
||||
near = camera.near;
|
||||
far = camera.far;
|
||||
zoom = camera.zoom;
|
||||
|
||||
// Off-axis stereoscopic effect based on
|
||||
// http://paulbourke.net/stereographics/stereorender/
|
||||
|
||||
var projectionMatrix = camera.projectionMatrix.clone();
|
||||
eyeSep = this.eyeSep / 2;
|
||||
var eyeSepOnProjection = eyeSep * near / focus;
|
||||
var ymax = ( near * Math.tan( _Math.DEG2RAD * fov * 0.5 ) ) / zoom;
|
||||
var xmin, xmax;
|
||||
|
||||
// translate xOffset
|
||||
|
||||
eyeLeft.elements[ 12 ] = - eyeSep;
|
||||
eyeRight.elements[ 12 ] = eyeSep;
|
||||
|
||||
// for left eye
|
||||
|
||||
xmin = - ymax * aspect + eyeSepOnProjection;
|
||||
xmax = ymax * aspect + eyeSepOnProjection;
|
||||
|
||||
projectionMatrix.elements[ 0 ] = 2 * near / ( xmax - xmin );
|
||||
projectionMatrix.elements[ 8 ] = ( xmax + xmin ) / ( xmax - xmin );
|
||||
|
||||
this.cameraL.projectionMatrix.copy( projectionMatrix );
|
||||
|
||||
// for right eye
|
||||
|
||||
xmin = - ymax * aspect - eyeSepOnProjection;
|
||||
xmax = ymax * aspect - eyeSepOnProjection;
|
||||
|
||||
projectionMatrix.elements[ 0 ] = 2 * near / ( xmax - xmin );
|
||||
projectionMatrix.elements[ 8 ] = ( xmax + xmin ) / ( xmax - xmin );
|
||||
|
||||
this.cameraR.projectionMatrix.copy( projectionMatrix );
|
||||
|
||||
}
|
||||
|
||||
this.cameraL.matrixWorld.copy( camera.matrixWorld ).multiply( eyeLeft );
|
||||
this.cameraR.matrixWorld.copy( camera.matrixWorld ).multiply( eyeRight );
|
||||
|
||||
};
|
||||
|
||||
} )()
|
||||
|
||||
} );
|
||||
|
||||
|
||||
export { StereoCamera };
|
Reference in New Issue
Block a user