浏览代码

WebVR: Moved setProjectionFromUnion method to internal WebVRUtils.

Mr.doob 6 年之前
父节点
当前提交
3c904f38ae

+ 1 - 65
src/cameras/ArrayCamera.js

@@ -3,7 +3,6 @@
  */
 
 import { PerspectiveCamera } from './PerspectiveCamera.js';
-import { Vector3 } from '../math/Vector3.js';
 
 function ArrayCamera( array ) {
 
@@ -17,70 +16,7 @@ ArrayCamera.prototype = Object.assign( Object.create( PerspectiveCamera.prototyp
 
 	constructor: ArrayCamera,
 
-	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 );
-
-		};
-
-	}(),
+	isArrayCamera: true
 
 } );
 

+ 2 - 1
src/renderers/webvr/WebVRManager.js

@@ -10,6 +10,7 @@ import { Quaternion } from '../../math/Quaternion.js';
 import { ArrayCamera } from '../../cameras/ArrayCamera.js';
 import { PerspectiveCamera } from '../../cameras/PerspectiveCamera.js';
 import { WebGLAnimation } from '../webgl/WebGLAnimation.js';
+import { setProjectionFromUnion } from './WebVRUtils.js';
 
 function WebVRManager( renderer ) {
 
@@ -323,7 +324,7 @@ function WebVRManager( renderer ) {
 		cameraL.projectionMatrix.fromArray( frameData.leftProjectionMatrix );
 		cameraR.projectionMatrix.fromArray( frameData.rightProjectionMatrix );
 
-		cameraVR.setProjectionFromUnion();
+		setProjectionFromUnion( cameraVR, cameraL, cameraR );
 
 		//
 

+ 67 - 0
src/renderers/webvr/WebVRUtils.js

@@ -0,0 +1,67 @@
+/**
+ * @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 };

+ 2 - 1
src/renderers/webvr/WebXRManager.js

@@ -7,6 +7,7 @@ import { Vector4 } from '../../math/Vector4.js';
 import { ArrayCamera } from '../../cameras/ArrayCamera.js';
 import { PerspectiveCamera } from '../../cameras/PerspectiveCamera.js';
 import { WebGLAnimation } from '../webgl/WebGLAnimation.js';
+import { setProjectionFromUnion } from './WebVRUtils.js';
 
 function WebXRManager( renderer ) {
 
@@ -181,7 +182,7 @@ function WebXRManager( renderer ) {
 
 			}
 
-			cameraVR.setProjectionFromUnion();
+			setProjectionFromUnion( cameraVR, cameraL, cameraR );
 
 			return cameraVR;