|
@@ -22755,26 +22755,6 @@ function WebGLMultiview( renderer, gl ) {
|
|
|
|
|
|
}
|
|
|
|
|
|
-/**
|
|
|
- * @author mrdoob / http://mrdoob.com/
|
|
|
- */
|
|
|
-
|
|
|
-function Group() {
|
|
|
-
|
|
|
- Object3D.call( this );
|
|
|
-
|
|
|
- this.type = 'Group';
|
|
|
-
|
|
|
-}
|
|
|
-
|
|
|
-Group.prototype = Object.assign( Object.create( Object3D.prototype ), {
|
|
|
-
|
|
|
- constructor: Group,
|
|
|
-
|
|
|
- isGroup: true
|
|
|
-
|
|
|
-} );
|
|
|
-
|
|
|
/**
|
|
|
* @author mrdoob / http://mrdoob.com/
|
|
|
*/
|
|
@@ -22796,505 +22776,24 @@ ArrayCamera.prototype = Object.assign( Object.create( PerspectiveCamera.prototyp
|
|
|
} );
|
|
|
|
|
|
/**
|
|
|
- * @author jsantell / https://www.jsantell.com/
|
|
|
* @author mrdoob / http://mrdoob.com/
|
|
|
*/
|
|
|
|
|
|
-var cameraLPos = new Vector3();
|
|
|
-var cameraRPos = new Vector3();
|
|
|
-
|
|
|
-/**
|
|
|
- * Assumes 2 cameras that are parallel 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.
|
|
|
- * Visualization of this technique: https://computergraphics.stackexchange.com/a/4765
|
|
|
- */
|
|
|
-function setProjectionFromUnion( camera, cameraL, cameraR ) {
|
|
|
-
|
|
|
- cameraLPos.setFromMatrixPosition( cameraL.matrixWorld );
|
|
|
- cameraRPos.setFromMatrixPosition( cameraR.matrixWorld );
|
|
|
-
|
|
|
- var ipd = cameraLPos.distanceTo( cameraRPos );
|
|
|
-
|
|
|
- var projL = cameraL.projectionMatrix.elements;
|
|
|
- var projR = cameraR.projectionMatrix.elements;
|
|
|
-
|
|
|
- // VR systems will have identical far and near planes, and
|
|
|
- // most likely identical top and bottom frustum extents.
|
|
|
- // Use the left camera for these values.
|
|
|
- var near = projL[ 14 ] / ( projL[ 10 ] - 1 );
|
|
|
- var far = projL[ 14 ] / ( projL[ 10 ] + 1 );
|
|
|
- var topFov = ( projL[ 9 ] + 1 ) / projL[ 5 ];
|
|
|
- var bottomFov = ( projL[ 9 ] - 1 ) / projL[ 5 ];
|
|
|
-
|
|
|
- var leftFov = ( projL[ 8 ] - 1 ) / projL[ 0 ];
|
|
|
- var rightFov = ( projR[ 8 ] + 1 ) / projR[ 0 ];
|
|
|
- var left = near * leftFov;
|
|
|
- var right = near * rightFov;
|
|
|
-
|
|
|
- // Calculate the new camera's position offset from the
|
|
|
- // left camera. xOffset should be roughly half `ipd`.
|
|
|
- var zOffset = ipd / ( - leftFov + rightFov );
|
|
|
- var xOffset = zOffset * - leftFov;
|
|
|
-
|
|
|
- // 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 );
|
|
|
+function Group() {
|
|
|
|
|
|
- // 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 left2 = left - xOffset;
|
|
|
- var right2 = right + ( ipd - xOffset );
|
|
|
- var top2 = topFov * far / far2 * near2;
|
|
|
- var bottom2 = bottomFov * far / far2 * near2;
|
|
|
+ Object3D.call( this );
|
|
|
|
|
|
- camera.projectionMatrix.makePerspective( left2, right2, top2, bottom2, near2, far2 );
|
|
|
+ this.type = 'Group';
|
|
|
|
|
|
}
|
|
|
|
|
|
-/**
|
|
|
- * @author mrdoob / http://mrdoob.com/
|
|
|
- */
|
|
|
-
|
|
|
-function WebVRManager( renderer ) {
|
|
|
-
|
|
|
- var renderWidth, renderHeight;
|
|
|
- var scope = this;
|
|
|
-
|
|
|
- var device = null;
|
|
|
- var frameData = null;
|
|
|
-
|
|
|
- var controllers = [];
|
|
|
- var standingMatrix = new Matrix4();
|
|
|
- var standingMatrixInverse = new Matrix4();
|
|
|
-
|
|
|
- var framebufferScaleFactor = 1.0;
|
|
|
-
|
|
|
- var referenceSpaceType = 'local-floor';
|
|
|
-
|
|
|
- if ( typeof window !== 'undefined' && 'VRFrameData' in window ) {
|
|
|
-
|
|
|
- frameData = new window.VRFrameData();
|
|
|
- window.addEventListener( 'vrdisplaypresentchange', onVRDisplayPresentChange, false );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- var matrixWorldInverse = new Matrix4();
|
|
|
- var tempQuaternion = new Quaternion();
|
|
|
- var tempPosition = new Vector3();
|
|
|
-
|
|
|
- var tempCamera = new PerspectiveCamera();
|
|
|
-
|
|
|
- var cameraL = new PerspectiveCamera();
|
|
|
- cameraL.viewport = new Vector4();
|
|
|
- cameraL.layers.enable( 1 );
|
|
|
-
|
|
|
- var cameraR = new PerspectiveCamera();
|
|
|
- cameraR.viewport = new Vector4();
|
|
|
- cameraR.layers.enable( 2 );
|
|
|
-
|
|
|
- var cameraVR = new ArrayCamera( [ cameraL, cameraR ] );
|
|
|
- cameraVR.layers.enable( 1 );
|
|
|
- cameraVR.layers.enable( 2 );
|
|
|
-
|
|
|
- //
|
|
|
-
|
|
|
- function isPresenting() {
|
|
|
-
|
|
|
- return device !== null && device.isPresenting === true;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- var currentSize = new Vector2(), currentPixelRatio;
|
|
|
-
|
|
|
- function onVRDisplayPresentChange() {
|
|
|
-
|
|
|
- if ( isPresenting() ) {
|
|
|
-
|
|
|
- var eyeParameters = device.getEyeParameters( 'left' );
|
|
|
- renderWidth = 2 * eyeParameters.renderWidth * framebufferScaleFactor;
|
|
|
- renderHeight = eyeParameters.renderHeight * framebufferScaleFactor;
|
|
|
-
|
|
|
- currentPixelRatio = renderer.getPixelRatio();
|
|
|
- renderer.getSize( currentSize );
|
|
|
-
|
|
|
- renderer.setDrawingBufferSize( renderWidth, renderHeight, 1 );
|
|
|
-
|
|
|
- cameraL.viewport.set( 0, 0, renderWidth / 2, renderHeight );
|
|
|
- cameraR.viewport.set( renderWidth / 2, 0, renderWidth / 2, renderHeight );
|
|
|
-
|
|
|
- animation.start();
|
|
|
-
|
|
|
- scope.dispatchEvent( { type: 'sessionstart' } );
|
|
|
-
|
|
|
- } else {
|
|
|
-
|
|
|
- if ( scope.enabled ) {
|
|
|
-
|
|
|
- renderer.setDrawingBufferSize( currentSize.width, currentSize.height, currentPixelRatio );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- animation.stop();
|
|
|
-
|
|
|
- scope.dispatchEvent( { type: 'sessionend' } );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- //
|
|
|
-
|
|
|
- var triggers = [];
|
|
|
- var grips = [];
|
|
|
-
|
|
|
- function findGamepad( id ) {
|
|
|
-
|
|
|
- var gamepads = navigator.getGamepads && navigator.getGamepads();
|
|
|
-
|
|
|
- for ( var i = 0, l = gamepads.length; i < l; i ++ ) {
|
|
|
-
|
|
|
- var gamepad = gamepads[ i ];
|
|
|
-
|
|
|
- if ( gamepad && ( gamepad.id === 'Daydream Controller' ||
|
|
|
- gamepad.id === 'Gear VR Controller' || gamepad.id === 'Oculus Go Controller' ||
|
|
|
- gamepad.id === 'OpenVR Gamepad' || gamepad.id.startsWith( 'Oculus Touch' ) ||
|
|
|
- gamepad.id.startsWith( 'HTC Vive Focus' ) ||
|
|
|
- gamepad.id.startsWith( 'Spatial Controller' ) ) ) {
|
|
|
-
|
|
|
- var hand = gamepad.hand;
|
|
|
-
|
|
|
- if ( id === 0 && ( hand === '' || hand === 'right' ) ) return gamepad;
|
|
|
- if ( id === 1 && ( hand === 'left' ) ) return gamepad;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- function updateControllers() {
|
|
|
-
|
|
|
- for ( var i = 0; i < controllers.length; i ++ ) {
|
|
|
-
|
|
|
- var controller = controllers[ i ];
|
|
|
-
|
|
|
- var gamepad = findGamepad( i );
|
|
|
-
|
|
|
- if ( gamepad !== undefined && gamepad.pose !== undefined ) {
|
|
|
-
|
|
|
- if ( gamepad.pose === null ) return;
|
|
|
-
|
|
|
- // Pose
|
|
|
-
|
|
|
- var pose = gamepad.pose;
|
|
|
-
|
|
|
- if ( pose.hasPosition === false ) controller.position.set( 0.2, - 0.6, - 0.05 );
|
|
|
-
|
|
|
- if ( pose.position !== null ) controller.position.fromArray( pose.position );
|
|
|
- if ( pose.orientation !== null ) controller.quaternion.fromArray( pose.orientation );
|
|
|
- controller.matrix.compose( controller.position, controller.quaternion, controller.scale );
|
|
|
- controller.matrix.premultiply( standingMatrix );
|
|
|
- controller.matrix.decompose( controller.position, controller.quaternion, controller.scale );
|
|
|
- controller.matrixWorldNeedsUpdate = true;
|
|
|
- controller.visible = true;
|
|
|
-
|
|
|
- // Trigger
|
|
|
-
|
|
|
- var buttonId = gamepad.id === 'Daydream Controller' ? 0 : 1;
|
|
|
-
|
|
|
- if ( triggers[ i ] === undefined ) triggers[ i ] = false;
|
|
|
-
|
|
|
- if ( triggers[ i ] !== gamepad.buttons[ buttonId ].pressed ) {
|
|
|
-
|
|
|
- triggers[ i ] = gamepad.buttons[ buttonId ].pressed;
|
|
|
-
|
|
|
- if ( triggers[ i ] === true ) {
|
|
|
-
|
|
|
- controller.dispatchEvent( { type: 'selectstart' } );
|
|
|
-
|
|
|
- } else {
|
|
|
-
|
|
|
- controller.dispatchEvent( { type: 'selectend' } );
|
|
|
- controller.dispatchEvent( { type: 'select' } );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- // Grip
|
|
|
- buttonId = 2;
|
|
|
-
|
|
|
- if ( grips[ i ] === undefined ) grips[ i ] = false;
|
|
|
-
|
|
|
- // Skip if the grip button doesn't exist on this controller
|
|
|
- if ( gamepad.buttons[ buttonId ] !== undefined ) {
|
|
|
-
|
|
|
- if ( grips[ i ] !== gamepad.buttons[ buttonId ].pressed ) {
|
|
|
-
|
|
|
- grips[ i ] = gamepad.buttons[ buttonId ].pressed;
|
|
|
-
|
|
|
- if ( grips[ i ] === true ) {
|
|
|
-
|
|
|
- controller.dispatchEvent( { type: 'squeezestart' } );
|
|
|
-
|
|
|
- } else {
|
|
|
-
|
|
|
- controller.dispatchEvent( { type: 'squeezeend' } );
|
|
|
- controller.dispatchEvent( { type: 'squeeze' } );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- } else {
|
|
|
-
|
|
|
- controller.visible = false;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- function updateViewportFromBounds( viewport, bounds ) {
|
|
|
-
|
|
|
- if ( bounds !== null && bounds.length === 4 ) {
|
|
|
-
|
|
|
- viewport.set( bounds[ 0 ] * renderWidth, bounds[ 1 ] * renderHeight, bounds[ 2 ] * renderWidth, bounds[ 3 ] * renderHeight );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- //
|
|
|
-
|
|
|
- this.enabled = false;
|
|
|
-
|
|
|
- this.getController = function ( id ) {
|
|
|
-
|
|
|
- var controller = controllers[ id ];
|
|
|
-
|
|
|
- if ( controller === undefined ) {
|
|
|
-
|
|
|
- controller = new Group();
|
|
|
- controller.matrixAutoUpdate = false;
|
|
|
- controller.visible = false;
|
|
|
-
|
|
|
- controllers[ id ] = controller;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- return controller;
|
|
|
-
|
|
|
- };
|
|
|
-
|
|
|
- this.getDevice = function () {
|
|
|
-
|
|
|
- return device;
|
|
|
-
|
|
|
- };
|
|
|
-
|
|
|
- this.setDevice = function ( value ) {
|
|
|
-
|
|
|
- if ( value !== undefined ) device = value;
|
|
|
-
|
|
|
- animation.setContext( value );
|
|
|
-
|
|
|
- };
|
|
|
-
|
|
|
- this.setFramebufferScaleFactor = function ( value ) {
|
|
|
-
|
|
|
- framebufferScaleFactor = value;
|
|
|
-
|
|
|
- };
|
|
|
-
|
|
|
- this.setReferenceSpaceType = function ( value ) {
|
|
|
-
|
|
|
- referenceSpaceType = value;
|
|
|
-
|
|
|
- };
|
|
|
-
|
|
|
- this.getCamera = function ( camera ) {
|
|
|
-
|
|
|
- var userHeight = referenceSpaceType === 'local-floor' ? 1.6 : 0;
|
|
|
-
|
|
|
- device.depthNear = camera.near;
|
|
|
- device.depthFar = camera.far;
|
|
|
-
|
|
|
- device.getFrameData( frameData );
|
|
|
-
|
|
|
- //
|
|
|
-
|
|
|
- if ( referenceSpaceType === 'local-floor' ) {
|
|
|
-
|
|
|
- var stageParameters = device.stageParameters;
|
|
|
-
|
|
|
- if ( stageParameters ) {
|
|
|
-
|
|
|
- standingMatrix.fromArray( stageParameters.sittingToStandingTransform );
|
|
|
-
|
|
|
- } else {
|
|
|
-
|
|
|
- standingMatrix.makeTranslation( 0, userHeight, 0 );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- var pose = frameData.pose;
|
|
|
-
|
|
|
- tempCamera.matrix.copy( standingMatrix );
|
|
|
- tempCamera.matrix.decompose( tempCamera.position, tempCamera.quaternion, tempCamera.scale );
|
|
|
-
|
|
|
- if ( pose.orientation !== null ) {
|
|
|
-
|
|
|
- tempQuaternion.fromArray( pose.orientation );
|
|
|
- tempCamera.quaternion.multiply( tempQuaternion );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- if ( pose.position !== null ) {
|
|
|
-
|
|
|
- tempQuaternion.setFromRotationMatrix( standingMatrix );
|
|
|
- tempPosition.fromArray( pose.position );
|
|
|
- tempPosition.applyQuaternion( tempQuaternion );
|
|
|
- tempCamera.position.add( tempPosition );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- tempCamera.updateMatrixWorld();
|
|
|
-
|
|
|
- //
|
|
|
-
|
|
|
- camera.matrixWorld.copy( tempCamera.matrixWorld );
|
|
|
-
|
|
|
- var children = camera.children;
|
|
|
-
|
|
|
- for ( var i = 0, l = children.length; i < l; i ++ ) {
|
|
|
-
|
|
|
- children[ i ].updateMatrixWorld( true );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- //
|
|
|
-
|
|
|
- cameraL.near = camera.near;
|
|
|
- cameraR.near = camera.near;
|
|
|
-
|
|
|
- cameraL.far = camera.far;
|
|
|
- cameraR.far = camera.far;
|
|
|
-
|
|
|
- cameraL.matrixWorldInverse.fromArray( frameData.leftViewMatrix );
|
|
|
- cameraR.matrixWorldInverse.fromArray( frameData.rightViewMatrix );
|
|
|
-
|
|
|
- // TODO (mrdoob) Double check this code
|
|
|
-
|
|
|
- standingMatrixInverse.getInverse( standingMatrix );
|
|
|
-
|
|
|
- if ( referenceSpaceType === 'local-floor' ) {
|
|
|
-
|
|
|
- cameraL.matrixWorldInverse.multiply( standingMatrixInverse );
|
|
|
- cameraR.matrixWorldInverse.multiply( standingMatrixInverse );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- var parent = camera.parent;
|
|
|
-
|
|
|
- if ( parent !== null ) {
|
|
|
-
|
|
|
- matrixWorldInverse.getInverse( parent.matrixWorld );
|
|
|
-
|
|
|
- cameraL.matrixWorldInverse.multiply( matrixWorldInverse );
|
|
|
- cameraR.matrixWorldInverse.multiply( matrixWorldInverse );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- // envMap and Mirror needs camera.matrixWorld
|
|
|
-
|
|
|
- cameraL.matrixWorld.getInverse( cameraL.matrixWorldInverse );
|
|
|
- cameraR.matrixWorld.getInverse( cameraR.matrixWorldInverse );
|
|
|
-
|
|
|
- cameraL.projectionMatrix.fromArray( frameData.leftProjectionMatrix );
|
|
|
- cameraR.projectionMatrix.fromArray( frameData.rightProjectionMatrix );
|
|
|
-
|
|
|
- setProjectionFromUnion( cameraVR, cameraL, cameraR );
|
|
|
-
|
|
|
- //
|
|
|
-
|
|
|
- var layers = device.getLayers();
|
|
|
-
|
|
|
- if ( layers.length ) {
|
|
|
-
|
|
|
- var layer = layers[ 0 ];
|
|
|
-
|
|
|
- updateViewportFromBounds( cameraL.viewport, layer.leftBounds );
|
|
|
- updateViewportFromBounds( cameraR.viewport, layer.rightBounds );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- updateControllers();
|
|
|
-
|
|
|
- return cameraVR;
|
|
|
-
|
|
|
- };
|
|
|
-
|
|
|
- this.getStandingMatrix = function () {
|
|
|
-
|
|
|
- return standingMatrix;
|
|
|
-
|
|
|
- };
|
|
|
-
|
|
|
- this.isPresenting = isPresenting;
|
|
|
-
|
|
|
- // Animation Loop
|
|
|
-
|
|
|
- var animation = new WebGLAnimation();
|
|
|
-
|
|
|
- this.setAnimationLoop = function ( callback ) {
|
|
|
-
|
|
|
- animation.setAnimationLoop( callback );
|
|
|
-
|
|
|
- if ( isPresenting() ) animation.start();
|
|
|
-
|
|
|
- };
|
|
|
-
|
|
|
- this.submitFrame = function () {
|
|
|
-
|
|
|
- if ( isPresenting() ) device.submitFrame();
|
|
|
-
|
|
|
- };
|
|
|
-
|
|
|
- this.dispose = function () {
|
|
|
-
|
|
|
- if ( typeof window !== 'undefined' ) {
|
|
|
-
|
|
|
- window.removeEventListener( 'vrdisplaypresentchange', onVRDisplayPresentChange );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- };
|
|
|
-
|
|
|
- // DEPRECATED
|
|
|
-
|
|
|
- this.setFrameOfReferenceType = function () {
|
|
|
-
|
|
|
- console.warn( 'THREE.WebVRManager: setFrameOfReferenceType() has been deprecated.' );
|
|
|
+Group.prototype = Object.assign( Object.create( Object3D.prototype ), {
|
|
|
|
|
|
- };
|
|
|
+ constructor: Group,
|
|
|
|
|
|
-}
|
|
|
+ isGroup: true
|
|
|
|
|
|
-Object.assign( WebVRManager.prototype, EventDispatcher.prototype );
|
|
|
+} );
|
|
|
|
|
|
/**
|
|
|
* @author mrdoob / http://mrdoob.com/
|
|
@@ -23470,6 +22969,66 @@ function WebXRManager( renderer, gl ) {
|
|
|
|
|
|
//
|
|
|
|
|
|
+ var cameraLPos = new Vector3();
|
|
|
+ var cameraRPos = new Vector3();
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @author jsantell / https://www.jsantell.com/
|
|
|
+ *
|
|
|
+ * Assumes 2 cameras that are parallel 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.
|
|
|
+ * Visualization of this technique: https://computergraphics.stackexchange.com/a/4765
|
|
|
+ */
|
|
|
+ function setProjectionFromUnion( camera, cameraL, cameraR ) {
|
|
|
+
|
|
|
+ cameraLPos.setFromMatrixPosition( cameraL.matrixWorld );
|
|
|
+ cameraRPos.setFromMatrixPosition( cameraR.matrixWorld );
|
|
|
+
|
|
|
+ var ipd = cameraLPos.distanceTo( cameraRPos );
|
|
|
+
|
|
|
+ var projL = cameraL.projectionMatrix.elements;
|
|
|
+ var projR = cameraR.projectionMatrix.elements;
|
|
|
+
|
|
|
+ // VR systems will have identical far and near planes, and
|
|
|
+ // most likely identical top and bottom frustum extents.
|
|
|
+ // Use the left camera for these values.
|
|
|
+ var near = projL[ 14 ] / ( projL[ 10 ] - 1 );
|
|
|
+ var far = projL[ 14 ] / ( projL[ 10 ] + 1 );
|
|
|
+ var topFov = ( projL[ 9 ] + 1 ) / projL[ 5 ];
|
|
|
+ var bottomFov = ( projL[ 9 ] - 1 ) / projL[ 5 ];
|
|
|
+
|
|
|
+ var leftFov = ( projL[ 8 ] - 1 ) / projL[ 0 ];
|
|
|
+ var rightFov = ( projR[ 8 ] + 1 ) / projR[ 0 ];
|
|
|
+ var left = near * leftFov;
|
|
|
+ var right = near * rightFov;
|
|
|
+
|
|
|
+ // Calculate the new camera's position offset from the
|
|
|
+ // left camera. xOffset should be roughly half `ipd`.
|
|
|
+ var zOffset = ipd / ( - leftFov + rightFov );
|
|
|
+ var xOffset = zOffset * - leftFov;
|
|
|
+
|
|
|
+ // 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 left2 = left - xOffset;
|
|
|
+ var right2 = right + ( ipd - xOffset );
|
|
|
+ var top2 = topFov * far / far2 * near2;
|
|
|
+ var bottom2 = bottomFov * far / far2 * near2;
|
|
|
+
|
|
|
+ camera.projectionMatrix.makePerspective( left2, right2, top2, bottom2, near2, far2 );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
function updateCamera( camera, parent ) {
|
|
|
|
|
|
if ( parent === null ) {
|
|
@@ -23895,7 +23454,7 @@ function WebGLRenderer( parameters ) {
|
|
|
|
|
|
// xr
|
|
|
|
|
|
- var xr = ( typeof navigator !== 'undefined' && 'xr' in navigator ) ? new WebXRManager( _this, _gl ) : new WebVRManager( _this );
|
|
|
+ var xr = new WebXRManager( _this, _gl );
|
|
|
|
|
|
this.xr = xr;
|
|
|
|
|
@@ -49960,27 +49519,6 @@ Object.defineProperties( WebGLRenderTarget.prototype, {
|
|
|
|
|
|
//
|
|
|
|
|
|
-Object.defineProperties( WebVRManager.prototype, {
|
|
|
-
|
|
|
- standing: {
|
|
|
- set: function ( /* value */ ) {
|
|
|
-
|
|
|
- console.warn( 'THREE.WebVRManager: .standing has been removed.' );
|
|
|
-
|
|
|
- }
|
|
|
- },
|
|
|
- userHeight: {
|
|
|
- set: function ( /* value */ ) {
|
|
|
-
|
|
|
- console.warn( 'THREE.WebVRManager: .userHeight has been removed.' );
|
|
|
-
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
-} );
|
|
|
-
|
|
|
-//
|
|
|
-
|
|
|
Object.defineProperties( Audio.prototype, {
|
|
|
|
|
|
load: {
|