瀏覽代碼

Updated VRControls and VREffect to support WebVR v1

Retained support for older versions of the API as well. Class interfaces
are unchanged.
Brandon Jones 10 年之前
父節點
當前提交
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 );
 

粤ICP备19079148号