提交 3c904f38 编写于 作者: M Mr.doob

WebVR: Moved setProjectionFromUnion method to internal WebVRUtils.

上级 f565ac40
...@@ -3,7 +3,6 @@ ...@@ -3,7 +3,6 @@
*/ */
import { PerspectiveCamera } from './PerspectiveCamera.js'; import { PerspectiveCamera } from './PerspectiveCamera.js';
import { Vector3 } from '../math/Vector3.js';
function ArrayCamera( array ) { function ArrayCamera( array ) {
...@@ -17,70 +16,7 @@ ArrayCamera.prototype = Object.assign( Object.create( PerspectiveCamera.prototyp ...@@ -17,70 +16,7 @@ ArrayCamera.prototype = Object.assign( Object.create( PerspectiveCamera.prototyp
constructor: ArrayCamera, constructor: ArrayCamera,
isArrayCamera: true, isArrayCamera: true
/**
* Assumes 2 cameras that are perpendicular and share an X-axis, and that
* the cameras' projection and world matrices have already been set.
* And that near and far planes are identical for both cameras.
*/
setProjectionFromUnion: function () {
var cameraLPos = new Vector3();
var cameraRPos = new Vector3();
return function () {
cameraLPos.setFromMatrixPosition( this.cameras[ 0 ].matrixWorld );
cameraRPos.setFromMatrixPosition( this.cameras[ 1 ].matrixWorld );
var ipd = cameraLPos.distanceTo( cameraRPos );
var projL = this.cameras[ 0 ].projectionMatrix;
var projR = this.cameras[ 1 ].projectionMatrix;
// VR systems will have identical far and near planes, and
// most likely identical top and bottom frustum extents.
// via: https://computergraphics.stackexchange.com/a/4765
var near = projL[ 14 ] / ( projL[ 10 ] - 1 );
var far = projL[ 14 ] / ( projL[ 10 ] + 1 );
var leftFovL = ( projL[ 8 ] - 1 ) / projL[ 0 ];
var rightFovR = ( projR[ 8 ] + 1 ) / projR[ 0 ];
var leftL = leftFovL * near;
var rightR = rightFovR * near;
var topL = near * ( projL[ 9 ] + 1 ) / projL[ 5 ];
var topR = near * ( projR[ 9 ] + 1 ) / projR[ 5 ];
var bottomL = near * ( projL[ 9 ] - 1 ) / projL[ 5 ];
var bottomR = near * ( projR[ 9 ] - 1 ) / projR[ 5 ];
// Calculate the new camera's position offset from the
// left camera.
var zOffset = ipd / ( leftFovL + rightFovR );
var xOffset = zOffset * leftFovL;
// TODO: Better way to apply this offset?
this.cameras[ 0 ].matrixWorld.decompose( this.position, this.quaternion, this.scale );
this.translateX( xOffset );
this.translateZ( - zOffset );
this.matrixWorld.compose( this.position, this.quaternion, this.scale );
this.matrixWorldInverse.getInverse( this.matrixWorld );
// Find the union of the frustum values of the cameras and scale
// the values so that the near plane's position does not change in world space,
// although must now be relative to the new union camera.
var near2 = near + zOffset;
var far2 = far + zOffset;
var left = leftL - xOffset;
var right = rightR + ( ipd - xOffset );
var top = Math.max( topL, topR );
var bottom = Math.min( bottomL, bottomR );
this.projectionMatrix.makePerspective( left, right, top, bottom, near2, far2 );
};
}(),
} ); } );
......
...@@ -10,6 +10,7 @@ import { Quaternion } from '../../math/Quaternion.js'; ...@@ -10,6 +10,7 @@ import { Quaternion } from '../../math/Quaternion.js';
import { ArrayCamera } from '../../cameras/ArrayCamera.js'; import { ArrayCamera } from '../../cameras/ArrayCamera.js';
import { PerspectiveCamera } from '../../cameras/PerspectiveCamera.js'; import { PerspectiveCamera } from '../../cameras/PerspectiveCamera.js';
import { WebGLAnimation } from '../webgl/WebGLAnimation.js'; import { WebGLAnimation } from '../webgl/WebGLAnimation.js';
import { setProjectionFromUnion } from './WebVRUtils.js';
function WebVRManager( renderer ) { function WebVRManager( renderer ) {
...@@ -323,7 +324,7 @@ function WebVRManager( renderer ) { ...@@ -323,7 +324,7 @@ function WebVRManager( renderer ) {
cameraL.projectionMatrix.fromArray( frameData.leftProjectionMatrix ); cameraL.projectionMatrix.fromArray( frameData.leftProjectionMatrix );
cameraR.projectionMatrix.fromArray( frameData.rightProjectionMatrix ); cameraR.projectionMatrix.fromArray( frameData.rightProjectionMatrix );
cameraVR.setProjectionFromUnion(); setProjectionFromUnion( cameraVR, cameraL, cameraR );
// //
......
/**
* @author jsantell / https://www.jsantell.com/
* @author mrdoob / http://mrdoob.com/
*/
import { Vector3 } from '../../math/Vector3.js';
var cameraLPos = new Vector3();
var cameraRPos = new Vector3();
/**
* Assumes 2 cameras that are perpendicular and share an X-axis, and that
* the cameras' projection and world matrices have already been set.
* And that near and far planes are identical for both cameras.
*/
function setProjectionFromUnion( camera, cameraL, cameraR ) {
cameraLPos.setFromMatrixPosition( cameraL.matrixWorld );
cameraRPos.setFromMatrixPosition( cameraR.matrixWorld );
var ipd = cameraLPos.distanceTo( cameraRPos );
var projL = cameraL.projectionMatrix;
var projR = cameraR.projectionMatrix;
// VR systems will have identical far and near planes, and
// most likely identical top and bottom frustum extents.
// via: https://computergraphics.stackexchange.com/a/4765
var near = projL[ 14 ] / ( projL[ 10 ] - 1 );
var far = projL[ 14 ] / ( projL[ 10 ] + 1 );
var leftFovL = ( projL[ 8 ] - 1 ) / projL[ 0 ];
var rightFovR = ( projR[ 8 ] + 1 ) / projR[ 0 ];
var leftL = leftFovL * near;
var rightR = rightFovR * near;
var topL = near * ( projL[ 9 ] + 1 ) / projL[ 5 ];
var topR = near * ( projR[ 9 ] + 1 ) / projR[ 5 ];
var bottomL = near * ( projL[ 9 ] - 1 ) / projL[ 5 ];
var bottomR = near * ( projR[ 9 ] - 1 ) / projR[ 5 ];
// Calculate the new camera's position offset from the
// left camera.
var zOffset = ipd / ( leftFovL + rightFovR );
var xOffset = zOffset * leftFovL;
// TODO: Better way to apply this offset?
cameraL.matrixWorld.decompose( camera.position, camera.quaternion, camera.scale );
camera.translateX( xOffset );
camera.translateZ( - zOffset );
camera.matrixWorld.compose( camera.position, camera.quaternion, camera.scale );
camera.matrixWorldInverse.getInverse( camera.matrixWorld );
// Find the union of the frustum values of the cameras and scale
// the values so that the near plane's position does not change in world space,
// although must now be relative to the new union camera.
var near2 = near + zOffset;
var far2 = far + zOffset;
var left = leftL - xOffset;
var right = rightR + ( ipd - xOffset );
var top = Math.max( topL, topR );
var bottom = Math.min( bottomL, bottomR );
camera.projectionMatrix.makePerspective( left, right, top, bottom, near2, far2 );
}
export { setProjectionFromUnion };
...@@ -7,6 +7,7 @@ import { Vector4 } from '../../math/Vector4.js'; ...@@ -7,6 +7,7 @@ import { Vector4 } from '../../math/Vector4.js';
import { ArrayCamera } from '../../cameras/ArrayCamera.js'; import { ArrayCamera } from '../../cameras/ArrayCamera.js';
import { PerspectiveCamera } from '../../cameras/PerspectiveCamera.js'; import { PerspectiveCamera } from '../../cameras/PerspectiveCamera.js';
import { WebGLAnimation } from '../webgl/WebGLAnimation.js'; import { WebGLAnimation } from '../webgl/WebGLAnimation.js';
import { setProjectionFromUnion } from './WebVRUtils.js';
function WebXRManager( renderer ) { function WebXRManager( renderer ) {
...@@ -181,7 +182,7 @@ function WebXRManager( renderer ) { ...@@ -181,7 +182,7 @@ function WebXRManager( renderer ) {
} }
cameraVR.setProjectionFromUnion(); setProjectionFromUnion( cameraVR, cameraL, cameraR );
return cameraVR; return cameraVR;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册