Переглянути джерело

Editor: Use WebXR's offerSession when available. (#27773)

mrdoob 1 рік тому
батько
коміт
698079ae0a
3 змінених файлів з 52 додано та 29 видалено
  1. 2 0
      editor/js/Editor.js
  2. 34 25
      editor/js/Menubar.View.js
  3. 16 4
      editor/js/Viewport.XR.js

+ 2 - 0
editor/js/Editor.js

@@ -30,6 +30,8 @@ function Editor() {
 		// xr
 
 		enterXR: new Signal(),
+		offerXR: new Signal(),
+		leaveXR: new Signal(),
 
 		// notifications
 

+ 34 - 25
editor/js/Menubar.View.js

@@ -2,6 +2,7 @@ import { UIPanel, UIRow } from './libs/ui.js';
 
 function MenubarView( editor ) {
 
+	const signals = editor.signals;
 	const strings = editor.strings;
 
 	const container = new UIPanel();
@@ -48,50 +49,58 @@ function MenubarView( editor ) {
 	} );
 	options.add( option );
 
-	// VR (Work in progress)
+	// XR (Work in progress)
 
 	if ( 'xr' in navigator ) {
 
-		navigator.xr.isSessionSupported( 'immersive-ar' )
-			.then( function ( supported ) {
+		if ( 'offerSession' in navigator.xr ) {
 
-				if ( supported ) {
+			signals.offerXR.dispatch( 'immersive-ar' );
 
-					const option = new UIRow();
-					option.setClass( 'option' );
-					option.setTextContent( 'AR' );
-					option.onClick( function () {
+		} else {
 
-						editor.signals.enterXR.dispatch( 'immersive-ar' );
+			navigator.xr.isSessionSupported( 'immersive-ar' )
+				.then( function ( supported ) {
 
-					} );
-					options.add( option );
+					if ( supported ) {
 
-				} else {
+						const option = new UIRow();
+						option.setClass( 'option' );
+						option.setTextContent( 'AR' );
+						option.onClick( function () {
 
-					navigator.xr.isSessionSupported( 'immersive-vr' )
-						.then( function ( supported ) {
+							signals.enterXR.dispatch( 'immersive-ar' );
 
-							if ( supported ) {
+						} );
+						options.add( option );
 
-								const option = new UIRow();
-								option.setClass( 'option' );
-								option.setTextContent( 'VR' );
-								option.onClick( function () {
+					} else {
 
-									editor.signals.enterXR.dispatch( 'immersive-vr' );
+						navigator.xr.isSessionSupported( 'immersive-vr' )
+							.then( function ( supported ) {
 
-								} );
-								options.add( option );
+								if ( supported ) {
 
-							}
+									const option = new UIRow();
+									option.setClass( 'option' );
+									option.setTextContent( 'VR' );
+									option.onClick( function () {
 
-						} );
+										signals.enterXR.dispatch( 'immersive-vr' );
+
+									} );
+									options.add( option );
+
+								}
 
-				}
+							} );
+
+					}
 
 			} );
 
+		}
+
 	}
 
 	return container;

+ 16 - 4
editor/js/Viewport.XR.js

@@ -154,19 +154,31 @@ class XR {
 			editor.camera.copy( camera );
 
 			signals.windowResize.dispatch();
+			signals.leaveXR.dispatch();
 
 		};
 
 		// signals
 
+		const sessionInit = { optionalFeatures: [ 'local-floor' ] };
+
 		signals.enterXR.add( ( mode ) => {
 
-			if ( 'xr' in navigator ) {
+			navigator.xr.requestSession( mode, sessionInit ).then( onSessionStarted );
 
-				const sessionInit = { optionalFeatures: [ 'local-floor' ] };
-				navigator.xr.requestSession( mode, sessionInit ).then( onSessionStarted );
+		} );
 
-			}
+		signals.offerXR.add( function ( mode ) {
+
+			navigator.xr.offerSession( mode, sessionInit )
+				.then( onSessionStarted );
+
+			signals.leaveXR.add( function () {
+
+				navigator.xr.offerSession( mode, sessionInit )
+					.then( onSessionStarted );
+	
+			} );
 
 		} );