瀏覽代碼

Updated VRControls and VREffect to support WebVR v1

Retained support for older versions of the API as well. Class interfaces
are unchanged.
Brandon Jones 9 年之前
父節點
當前提交
5dabf29fe0
共有 4 個文件被更改,包括 147 次插入30 次删除
  1. 43 10
      examples/js/controls/VRControls.js
  2. 102 18
      examples/js/effects/VREffect.js
  3. 1 1
      examples/webvr_cubes.html
  4. 1 1
      examples/webvr_stereo_pano.html

+ 43 - 10
examples/js/controls/VRControls.js

@@ -13,7 +13,8 @@ THREE.VRControls = function ( object, onError ) {
 
 		for ( var i = 0; i < devices.length; i ++ ) {
 
-			if ( devices[ i ] instanceof PositionSensorVRDevice ) {
+			if ( devices[ i ] instanceof VRDisplay ||
+				 devices[ i ] instanceof PositionSensorVRDevice ) {
 
 				vrInputs.push( devices[ i ] );
 
@@ -23,14 +24,19 @@ THREE.VRControls = function ( object, onError ) {
 
 		if ( vrInputs.length === 0 ) {
 
-			if ( onError ) onError( 'PositionSensorVRDevice not available' );
+			if ( onError ) onError( 'VR inputs not available' );
 
 		}
 
 	}
 
-	if ( navigator.getVRDevices ) {
+	if ( navigator.getVRDisplays ) {
 
+		navigator.getVRDisplays().then( gotVRDevices );
+
+	} else if ( navigator.getVRDevices ) {
+
+		// Deprecated API.
 		navigator.getVRDevices().then( gotVRDevices );
 
 	}
@@ -47,17 +53,38 @@ THREE.VRControls = function ( object, onError ) {
 
 			var vrInput = vrInputs[ i ];
 
-			var state = vrInput.getState();
+			if ( vrInput.getPose ) {
 
-			if ( state.orientation !== null ) {
+				var pose = vrInput.getPose();
 
-				object.quaternion.copy( state.orientation );
+				if ( pose.orientation !== null ) {
 
-			}
+					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 );
+
+				}
 
 			}
 
@@ -71,12 +98,18 @@ THREE.VRControls = function ( object, onError ) {
 
 			var vrInput = vrInputs[ i ];
 
-			if ( vrInput.resetSensor !== undefined ) {
+			if ( vrInput.resetPose !== undefined ) {
+
+				vrInput.resetPose();
+
+			} else if ( vrInput.resetSensor !== undefined ) {
 
+				// Deprecated API.
 				vrInput.resetSensor();
 
 			} else if ( vrInput.zeroSensor !== undefined ) {
 
+				// Really deprecated API.
 				vrInput.zeroSensor();
 
 			}

+ 102 - 18
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 ( devices[ i ] instanceof VRDisplay ) {
 
 				vrHMD = devices[ i ];
+				deprecatedAPI = false;
+				break; // We keep the first we encounter
+
+			} else if ( 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,34 +69,72 @@ 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 ( deprecatedAPI ) {
+
+			isPresenting = document.mozFullScreenElement || document.webkitFullscreenElement;
+
+		}
+
+	}, false );
+
+	window.addEventListener( 'vrdisplaypresentchange', function () {
+
+		isPresenting = vrHMD.isPresenting;
 
 	}, false );
 
 	this.setFullScreen = function ( boolean ) {
 
 		if ( vrHMD === undefined ) return;
-		if ( isFullscreen === boolean ) return;
+		if ( isPresenting === boolean ) return;
+
+		if ( !deprecatedAPI ) {
+
+			if ( boolean ) {
+
+				vrHMD.requestPresent( { source: canvas } );
+
+			} else {
+
+				vrHMD.exitPresent();
 
-		if ( canvas.mozRequestFullScreen ) {
+			}
+
+		} else {
+
+			if ( canvas.mozRequestFullScreen ) {
+
+				canvas.mozRequestFullScreen( { vrDisplay: vrHMD } );
+
+			} else if ( canvas.webkitRequestFullscreen ) {
 
-			canvas.mozRequestFullScreen( { vrDisplay: vrHMD } );
+				canvas.webkitRequestFullscreen( { vrDisplay: vrHMD } );
 
-		} else if ( canvas.webkitRequestFullscreen ) {
+			} else {
 
-			canvas.webkitRequestFullscreen( { vrDisplay: vrHMD } );
+				console.error( 'No compatible requestFullscreen method found' );
+
+			}
 
 		}
 
 	};
 
+	this.requestPresent = function () {
+		this.setFullScreen( true );
+	};
+
+	this.exitPresent = function () {
+		this.setFullScreen( false );
+	};
+
 	// render
 
 	var cameraL = new THREE.PerspectiveCamera();
@@ -98,12 +150,38 @@ THREE.VREffect = function ( renderer, onError ) {
 			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 ) {
+
+				var renderWidth = Math.max(eyeParamsL.renderWidth, eyeParamsR.renderWidth);
+				var renderHeight = Math.max(eyeParamsL.renderHeight, eyeParamsR.renderHeight);
+
+				eyeTranslationL.fromArray(eyeParamsL.offset);
+				eyeTranslationR.fromArray(eyeParamsR.offset);
+				eyeFOVL = eyeParamsL.fieldOfView;
+				eyeFOVR = eyeParamsR.fieldOfView;
+				renderRectL = {
+					x: 0,
+					y: 0,
+					width: renderWidth,
+					height: renderHeight
+				};
+				renderRectR =  {
+					x: renderWidth,
+					y: 0,
+					width: renderWidth,
+					height: renderHeight
+				};
+
+			} else {
+
+				eyeTranslationL.copy(eyeParamsL.eyeTranslation);
+				eyeTranslationR.copy(eyeParamsR.eyeTranslation);
+				eyeFOVL = eyeParamsL.recommendedFieldOfView;
+				eyeFOVR = eyeParamsR.recommendedFieldOfView;
+				renderRectL = eyeParamsL.renderRect;
+				renderRectR = eyeParamsR.renderRect;
+
+			}
 
 			if ( Array.isArray( scene ) ) {
 
@@ -151,6 +229,12 @@ THREE.VREffect = function ( renderer, onError ) {
 
 			renderer.setScissorTest( false );
 
+			if ( isPresenting && !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 );