Bladeren bron

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 jaren geleden
bovenliggende
commit
5dabf29fe0
4 gewijzigde bestanden met toevoegingen van 147 en 30 verwijderingen
  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号