Browse Source

Merge branch 'master' into dev

Mr.doob 9 years ago
parent
commit
66e497d18c

+ 48 - 18
examples/js/controls/VRControls.js

@@ -7,30 +7,37 @@ THREE.VRControls = function ( object, onError ) {
 
 	var scope = this;
 
-	var vrInputs = [];
+	var vrInput;
 
 	function gotVRDevices( devices ) {
 
 		for ( var i = 0; i < devices.length; i ++ ) {
 
-			if ( devices[ i ] instanceof PositionSensorVRDevice ) {
+			if ( ( 'VRDisplay' in window && devices[ i ] instanceof VRDisplay ) ||
+				 ( 'PositionSensorVRDevice' in window && devices[ i ] instanceof PositionSensorVRDevice ) ) {
 
-				vrInputs.push( devices[ i ] );
+				vrInput = devices[ i ];
+				break;  // We keep the first we encounter
 
 			}
 
 		}
 
-		if ( vrInputs.length === 0 ) {
+		if ( !vrInput ) {
 
-			if ( onError ) onError( 'PositionSensorVRDevice not available' );
+			if ( onError ) onError( 'VR input not available.' );
 
 		}
 
 	}
 
-	if ( navigator.getVRDevices ) {
+	if ( navigator.getVRDisplays ) {
 
+		navigator.getVRDisplays().then( gotVRDevices );
+
+	} else if ( navigator.getVRDevices ) {
+
+		// Deprecated API.
 		navigator.getVRDevices().then( gotVRDevices );
 
 	}
@@ -43,21 +50,40 @@ THREE.VRControls = function ( object, onError ) {
 
 	this.update = function () {
 
-		for ( var i = 0; i < vrInputs.length; i ++ ) {
+		if ( vrInput ) {
 
-			var vrInput = vrInputs[ i ];
+			if ( vrInput.getPose ) {
 
-			var state = vrInput.getState();
+				var pose = vrInput.getPose();
 
-			if ( state.orientation !== null ) {
+				if ( pose.orientation !== null ) {
 
-				object.quaternion.copy( state.orientation );
+					object.quaternion.fromArray( pose.orientation );
 
-			}
+				}
+
+				if ( pose.position !== null ) {
+
+					object.position.fromArray( pose.position ).multiplyScalar( scope.scale );
+
+				}
+
+			} else {
 
-			if ( state.position !== null ) {
+				// Deprecated API.
+				var state = vrInput.getState();
 
-				object.position.copy( state.position ).multiplyScalar( scope.scale );
+				if ( state.orientation !== null ) {
+
+					object.quaternion.copy( state.orientation );
+
+				}
+
+				if ( state.position !== null ) {
+
+					object.position.copy( state.position ).multiplyScalar( scope.scale );
+
+				}
 
 			}
 
@@ -67,16 +93,20 @@ THREE.VRControls = function ( object, onError ) {
 
 	this.resetSensor = function () {
 
-		for ( var i = 0; i < vrInputs.length; i ++ ) {
+		if ( vrInput ) {
+
+			if ( vrInput.resetPose !== undefined ) {
 
-			var vrInput = vrInputs[ i ];
+				vrInput.resetPose();
 
-			if ( vrInput.resetSensor !== undefined ) {
+			} else if ( vrInput.resetSensor !== undefined ) {
 
+				// Deprecated API.
 				vrInput.resetSensor();
 
 			} else if ( vrInput.zeroSensor !== undefined ) {
 
+				// Really deprecated API.
 				vrInput.zeroSensor();
 
 			}
@@ -94,7 +124,7 @@ THREE.VRControls = function ( object, onError ) {
 
 	this.dispose = function () {
 
-		vrInputs = [];
+		vrInput = null;
 
 	};
 

+ 128 - 32
examples/js/effects/VREffect.js

@@ -12,17 +12,26 @@
 THREE.VREffect = function ( renderer, onError ) {
 
 	var vrHMD;
-	var eyeTranslationL, eyeFOVL, renderRectL;
-	var eyeTranslationR, eyeFOVR, renderRectR;
+	var deprecatedAPI = false;
+	var eyeTranslationL = new THREE.Vector3();
+	var eyeTranslationR = new THREE.Vector3();
+	var renderRectL, renderRectR;
+	var eyeFOVL, eyeFOVR;
 
 	function gotVRDevices( devices ) {
 
 		for ( var i = 0; i < devices.length; i ++ ) {
 
-			if ( devices[ i ] instanceof HMDVRDevice ) {
+			if ( 'VRDisplay' in window && devices[ i ] instanceof VRDisplay ) {
 
 				vrHMD = devices[ i ];
+				deprecatedAPI = false;
+				break; // We keep the first we encounter
+
+			} else if ( 'HMDVRDevice' in window && devices[ i ] instanceof HMDVRDevice ) {
 
+				vrHMD = devices[ i ];
+				deprecatedAPI = true;
 				break; // We keep the first we encounter
 
 			}
@@ -37,8 +46,13 @@ THREE.VREffect = function ( renderer, onError ) {
 
 	}
 
-	if ( navigator.getVRDevices ) {
+	if ( navigator.getVRDisplays ) {
+
+		navigator.getVRDisplays().then( gotVRDevices );
+
+	} else if ( navigator.getVRDevices ) {
 
+		// Deprecated API.
 		navigator.getVRDevices().then( gotVRDevices );
 
 	}
@@ -55,31 +69,90 @@ THREE.VREffect = function ( renderer, onError ) {
 
 	// fullscreen
 
-	var isFullscreen = false;
+	var isPresenting = false;
 
 	var canvas = renderer.domElement;
 	var fullscreenchange = canvas.mozRequestFullScreen ? 'mozfullscreenchange' : 'webkitfullscreenchange';
 
-	document.addEventListener( fullscreenchange, function ( event ) {
+	document.addEventListener( fullscreenchange, function () {
 
-		isFullscreen = document.mozFullScreenElement || document.webkitFullscreenElement;
+		if ( vrHMD && deprecatedAPI ) {
+
+			isPresenting = document.mozFullScreenElement || document.webkitFullscreenElement;
+
+		}
+
+	}, false );
+
+	window.addEventListener( 'vrdisplaypresentchange', function () {
+
+		isPresenting = vrHMD && vrHMD.isPresenting;
 
 	}, false );
 
 	this.setFullScreen = function ( boolean ) {
 
-		if ( vrHMD === undefined ) return;
-		if ( isFullscreen === boolean ) return;
+		return new Promise( function ( resolve, reject ) {
+
+			if ( vrHMD === undefined ) {
 
-		if ( canvas.mozRequestFullScreen ) {
+				reject( new Error( 'No VR hardware found.' ) );
+				return;
 
-			canvas.mozRequestFullScreen( { vrDisplay: vrHMD } );
+			}
+			if ( isPresenting === boolean ) {
+
+				resolve();
+				return;
 
-		} else if ( canvas.webkitRequestFullscreen ) {
+			}
 
-			canvas.webkitRequestFullscreen( { vrDisplay: vrHMD } );
+			if ( !deprecatedAPI ) {
 
-		}
+				if ( boolean ) {
+
+					resolve( vrHMD.requestPresent( { source: canvas } ) );
+
+				} else {
+
+					resolve( vrHMD.exitPresent() );
+
+				}
+
+			} else {
+
+				if ( canvas.mozRequestFullScreen ) {
+
+					canvas.mozRequestFullScreen( { vrDisplay: vrHMD } );
+					resolve();
+
+				} else if ( canvas.webkitRequestFullscreen ) {
+
+					canvas.webkitRequestFullscreen( { vrDisplay: vrHMD } );
+					resolve();
+
+				} else {
+
+					console.error( 'No compatible requestFullscreen method found.' );
+					reject( new Error( 'No compatible requestFullscreen method found.' ) );
+
+				}
+
+			}
+
+		});
+
+	};
+
+	this.requestPresent = function () {
+
+		return this.setFullScreen( true );
+
+	};
+
+	this.exitPresent = function () {
+
+		return this.setFullScreen( false );
 
 	};
 
@@ -93,17 +166,35 @@ THREE.VREffect = function ( renderer, onError ) {
 
 	this.render = function ( scene, camera ) {
 
-		if ( vrHMD ) {
+		if ( vrHMD && isPresenting ) {
+
+			var autoUpdate = scene.autoUpdate;
+
+			if ( autoUpdate ) {
+
+				scene.updateMatrixWorld();
+				scene.autoUpdate = false;
+
+			}
 
 			var eyeParamsL = vrHMD.getEyeParameters( 'left' );
 			var eyeParamsR = vrHMD.getEyeParameters( 'right' );
 
-			eyeTranslationL = eyeParamsL.eyeTranslation;
-			eyeTranslationR = eyeParamsR.eyeTranslation;
-			eyeFOVL = eyeParamsL.recommendedFieldOfView;
-			eyeFOVR = eyeParamsR.recommendedFieldOfView;
-			renderRectL = eyeParamsL.renderRect;
-			renderRectR = eyeParamsR.renderRect;
+			if ( !deprecatedAPI ) {
+
+				eyeTranslationL.fromArray( eyeParamsL.offset );
+				eyeTranslationR.fromArray( eyeParamsR.offset );
+				eyeFOVL = eyeParamsL.fieldOfView;
+				eyeFOVR = eyeParamsR.fieldOfView;
+
+			} else {
+
+				eyeTranslationL.copy( eyeParamsL.eyeTranslation );
+				eyeTranslationR.copy( eyeParamsR.eyeTranslation );
+				eyeFOVL = eyeParamsL.recommendedFieldOfView;
+				eyeFOVR = eyeParamsR.recommendedFieldOfView;
+
+			}
 
 			if ( Array.isArray( scene ) ) {
 
@@ -112,7 +203,11 @@ THREE.VREffect = function ( renderer, onError ) {
 
 			}
 
+			// When rendering we don't care what the recommended size is, only what the actual size
+			// of the backbuffer is.
 			var size = renderer.getSize();
+			renderRectL = { x: 0, y: 0, width: size.width / 2, height: size.height };
+			renderRectR = { x: size.width / 2, y: 0, width: size.width / 2, height: size.height };
 
 			renderer.setScissorTest( true );
 			renderer.clear();
@@ -129,28 +224,29 @@ THREE.VREffect = function ( renderer, onError ) {
 			cameraR.translateX( eyeTranslationR.x * this.scale );
 
 			// render left eye
-			if ( renderRectL === undefined ) {
-
-				renderRectL = { x: 0, y: 0, width: size.width / 2, height: size.height };
-
-			}
 			renderer.setViewport( renderRectL.x, renderRectL.y, renderRectL.width, renderRectL.height );
 			renderer.setScissor( renderRectL.x, renderRectL.y, renderRectL.width, renderRectL.height );
 			renderer.render( scene, cameraL );
 
 			// render right eye
-			if ( renderRectR === undefined ) {
-
-				renderRectR = { x: size.width / 2, y: 0, width: size.width / 2, height: size.height };
-
-			}
-
 			renderer.setViewport( renderRectR.x, renderRectR.y, renderRectR.width, renderRectR.height );
 			renderer.setScissor( renderRectR.x, renderRectR.y, renderRectR.width, renderRectR.height );
 			renderer.render( scene, cameraR );
 
 			renderer.setScissorTest( false );
 
+			if ( autoUpdate ) {
+
+				scene.autoUpdate = true;
+
+			}
+
+			if ( !deprecatedAPI ) {
+
+				vrHMD.submitFrame();
+
+			}
+
 			return;
 
 		}

+ 1 - 1
examples/webvr_cubes.html

@@ -127,7 +127,7 @@
 
 				var fullScreenButton = document.querySelector( '.full-screen' );
 
-				if ( navigator.getVRDevices === undefined ) {
+				if ( navigator.getVRDisplays === undefined && navigator.getVRDevices === undefined ) {
 
 					fullScreenButton.innerHTML = 'Your browser doesn\'t support WebVR';
 					fullScreenButton.classList.add('error');

+ 1 - 1
examples/webvr_stereo_pano.html

@@ -59,7 +59,7 @@
 			effect = new THREE.VREffect( renderer );
 
 
-			if ( navigator.getVRDevices ) {
+			if ( navigator.getVRDisplays || navigator.getVRDevices ) {
 
 				vrControls = new THREE.VRControls( camera, vrFallback );