Browse Source

WebXRManager: Introduce updateCamera() and refactor getCamera(). (#21886)

* WebXRManager: Introduce updateCamera() and refactor getCamera().

* Docs: Clean up.

* Examples: Clean up.

* WebXRManager: Add check for session in updateCamera().
Michael Herzog 4 năm trước cách đây
mục cha
commit
ec96437a05

+ 17 - 2
docs/api/en/renderers/webxr/WebXRManager.html

@@ -19,6 +19,11 @@
 
 		<h2>Properties</h2>
 
+		<h3>[property:Boolean cameraAutoUpdate]</h3>
+		<p>
+		Whether the manager's XR camera should be automatically updated or not. Default is *true*.
+		</p>
+
 		<h3>[property:Boolean enabled]</h3>
 		<p>
 		This flag notifies the renderer to be ready for XR rendering. Default is *false*. Set it to *true* if you are going
@@ -32,11 +37,14 @@
 
 		<h2>Methods</h2>
 
-		<h3>[method:ArrayCamera getCamera]( [param:PerspectiveCamera camera] )</h3>
+		<h3>[method:ArrayCamera getCamera]()</h3>
 		<p>
 		Returns an instance of [page:ArrayCamera] which represents the XR camera of the active XR session.
 		For each view it holds a separate camera object in its [page:ArrayCamera.cameras cameras] property.
-		The method requires the non-XR camera of the scene as a parameter.
+		</p>
+		<p>
+		The camera's *fov* is currently not used and does not reflect the fov of the XR camera. If you need the fov on app level,
+		you have to compute in manually from the XR camera's projection matrices.
 		</p>
 
 		<h3>[method:Group getController]( [param:Integer index] )</h3>
@@ -101,6 +109,13 @@
 		Please check out the [link:https://developer.mozilla.org/en-US/docs/Web/API/XRReferenceSpaceType MDN] for possible values and their use cases.
 		</p>
 
+		<h3>[method:void updateCamera]( [param:PerspectiveCamera camera] )</h3>
+		<p>
+		Updates the state of the XR camera. Use this method on app level if you set [page:.cameraAutoUpdate] to *false*.
+		The method requires the non-XR camera of the scene as a parameter. The passed in camera's transformation is automatically
+		adjusted to the position of the XR camera when calling this method.
+		</p>
+
 		<p>
 		Note: It is not possible to change the reference space type while presenting XR content.
 		</p>

+ 17 - 2
docs/api/zh/renderers/webxr/WebXRManager.html

@@ -19,6 +19,11 @@
 
 		<h2>Properties</h2>
 
+		<h3>[property:Boolean cameraAutoUpdate]</h3>
+		<p>
+		Whether the manager's XR camera should be automatically updated or not. Default is *true*.
+		</p>
+
 		<h3>[property:Boolean enabled]</h3>
 		<p>
 		This flag notifies the renderer to be ready for XR rendering. Default is *false*. Set it to *true* if you are going
@@ -32,11 +37,14 @@
 
 		<h2>Methods</h2>
 
-		<h3>[method:ArrayCamera getCamera]( [param:PerspectiveCamera camera] )</h3>
+		<h3>[method:ArrayCamera getCamera]()</h3>
 		<p>
 		Returns an instance of [page:ArrayCamera] which represents the XR camera of the active XR session.
 		For each view it holds a separate camera object in its [page:ArrayCamera.cameras cameras] property.
-		The method requires the non-XR camera of the scene as a parameter.
+		</p>
+		<p>
+		The camera's *fov* is currently not used and does not reflect the fov of the XR camera. If you need the fov on app level,
+		you have to compute in manually from the XR camera's projection matrices.
 		</p>
 
 		<h3>[method:Group getController]( [param:Integer index] )</h3>
@@ -101,6 +109,13 @@
 		Please check out the [link:https://developer.mozilla.org/en-US/docs/Web/API/XRReferenceSpaceType MDN] for possible values and their use cases.
 		</p>
 
+		<h3>[method:void updateCamera]( [param:PerspectiveCamera camera] )</h3>
+		<p>
+		Updates the state of the XR camera. Use this method on app level if you set [page:.cameraAutoUpdate] to *false*.
+		The method requires the non-XR camera of the scene as a parameter. The passed in camera's transformation is automatically
+		adjusted to the position of the XR camera when calling this method.
+		</p>
+
 		<p>
 		Note: It is not possible to change the reference space type while presenting XR content.
 		</p>

+ 3 - 1
examples/webxr_vr_handinput_pointerclick.html

@@ -241,7 +241,7 @@
 
 						const offset = entity.getComponent( OffsetFromCamera );
 						const object = entity.getComponent( Object3D ).object;
-						const xrCamera = renderer.xr.getCamera( this.camera );
+						const xrCamera = this.renderer.xr.getCamera();
 						object.position.x = xrCamera.position.x + offset.x;
 						object.position.y = xrCamera.position.y + offset.y;
 						object.position.z = xrCamera.position.z + offset.z;
@@ -308,6 +308,7 @@
 			renderer.outputEncoding = THREE.sRGBEncoding;
 			renderer.shadowMap.enabled = true;
 			renderer.xr.enabled = true;
+			renderer.xr.cameraAutoUpdate = false;
 
 			container.appendChild( renderer.domElement );
 
@@ -503,6 +504,7 @@
 
 			const delta = clock.getDelta();
 			const elapsedTime = clock.elapsedTime;
+			renderer.xr.updateCamera( camera );
 			world.execute( delta, elapsedTime );
 			renderer.render( scene, camera );
 

+ 3 - 1
examples/webxr_vr_handinput_pointerdrag.html

@@ -297,7 +297,7 @@
 
 						const offset = entity.getComponent( OffsetFromCamera );
 						const object = entity.getComponent( Object3D ).object;
-						const xrCamera = renderer.xr.getCamera( this.camera );
+						const xrCamera = this.renderer.xr.getCamera();
 						object.position.x = xrCamera.position.x + offset.x;
 						object.position.y = xrCamera.position.y + offset.y;
 						object.position.z = xrCamera.position.z + offset.z;
@@ -411,6 +411,7 @@
 			renderer.outputEncoding = THREE.sRGBEncoding;
 			renderer.shadowMap.enabled = true;
 			renderer.xr.enabled = true;
+			renderer.xr.cameraAutoUpdate = false;
 
 			container.appendChild( renderer.domElement );
 
@@ -581,6 +582,7 @@
 
 			const delta = clock.getDelta();
 			const elapsedTime = clock.elapsedTime;
+			renderer.xr.updateCamera( camera );
 			world.execute( delta, elapsedTime );
 			renderer.render( scene, camera );
 

+ 4 - 2
examples/webxr_vr_handinput_pressbutton.html

@@ -60,7 +60,7 @@
 				let buttonPressSound, buttonReleaseSound;
 				if ( this.renderer.xr.getSession() && ! this.soundAdded ) {
 
-					const xrCamera = this.renderer.xr.getCamera( camera );
+					const xrCamera = this.renderer.xr.getCamera();
 
 					const listener = new THREE.AudioListener();
 					xrCamera.add( listener );
@@ -301,7 +301,7 @@
 
 						const offset = entity.getComponent( OffsetFromCamera );
 						const object = entity.getComponent( Object3D ).object;
-						const xrCamera = renderer.xr.getCamera( this.camera );
+						const xrCamera = this.renderer.xr.getCamera();
 						object.position.x = xrCamera.position.x + offset.x;
 						object.position.y = xrCamera.position.y + offset.y;
 						object.position.z = xrCamera.position.z + offset.z;
@@ -368,6 +368,7 @@
 			renderer.outputEncoding = THREE.sRGBEncoding;
 			renderer.shadowMap.enabled = true;
 			renderer.xr.enabled = true;
+			renderer.xr.cameraAutoUpdate = false;
 
 			container.appendChild( renderer.domElement );
 
@@ -560,6 +561,7 @@
 
 			const delta = clock.getDelta();
 			const elapsedTime = clock.elapsedTime;
+			renderer.xr.updateCamera( camera );
 			world.execute( delta, elapsedTime );
 			renderer.render( scene, camera );
 

+ 3 - 1
src/renderers/WebGLRenderer.js

@@ -999,7 +999,9 @@ function WebGLRenderer( parameters ) {
 
 		if ( xr.enabled === true && xr.isPresenting === true ) {
 
-			camera = xr.getCamera( camera );
+			if ( xr.cameraAutoUpdate === true ) xr.updateCamera( camera );
+
+			camera = xr.getCamera(); // use XR camera for rendering
 
 		}
 

+ 8 - 1
src/renderers/webxr/WebXRManager.js

@@ -48,6 +48,7 @@ class WebXRManager extends EventDispatcher {
 
 		//
 
+		this.cameraAutoUpdate = true;
 		this.enabled = false;
 
 		this.isPresenting = false;
@@ -345,7 +346,9 @@ class WebXRManager extends EventDispatcher {
 
 		}
 
-		this.getCamera = function ( camera ) {
+		this.updateCamera = function ( camera ) {
+
+			if ( session === null ) return;
 
 			cameraVR.near = cameraR.near = cameraL.near = camera.near;
 			cameraVR.far = cameraR.far = cameraL.far = camera.far;
@@ -403,6 +406,10 @@ class WebXRManager extends EventDispatcher {
 
 			}
 
+		};
+
+		this.getCamera = function () {
+
 			return cameraVR;
 
 		};