Prechádzať zdrojové kódy

Move to setAnimationLoop model; optimized camera setup (once); pending tasks model for tiles schedulingCallback

Bruno Fanini 3 rokov pred
rodič
commit
dff61c3969
1 zmenil súbory, kde vykonal 64 pridanie a 28 odobranie
  1. 64 28
      example/vr.js

+ 64 - 28
example/vr.js

@@ -42,6 +42,8 @@ let box, sphere, grid;
 let raycaster, fwdVector, intersectRing;
 let offsetParent;
 let controller, controllerGrip;
+let xrSession = null;
+let tasks = [];
 
 let params = {
 
@@ -52,7 +54,6 @@ let params = {
 };
 
 init();
-animate();
 
 function init() {
 
@@ -69,6 +70,8 @@ function init() {
 	document.body.appendChild( renderer.domElement );
 	renderer.domElement.tabIndex = 1;
 
+	renderer.setAnimationLoop( frame );
+
 	// create workspace
 	workspace = new Group();
 	scene.add( workspace );
@@ -102,11 +105,15 @@ function init() {
 	tiles = new TilesRenderer( '../data/tileset.json' );
 	offsetParent.add( tiles.group );
 
+	// We set camera for tileset
+	tiles.setCamera( camera );
+	tiles.setResolutionFromRenderer( camera, renderer );
+
 
 	// We define a custom scheduling callback to handle also active WebXR sessions
 	const tilesSchedulingCB = func => {
 
-		setTimeout( func, 50 );
+		tasks.push( func );
 
 	};
 
@@ -219,16 +226,63 @@ function onWindowResize() {
 
 }
 
-function animate() {
+function handleCamera() {
+
+	// get the XR camera with a combined frustum for culling
+	if ( renderer.xr.isPresenting ) {
+
+		if ( xrSession === null ) { // We setup XR camera once
+
+			// remove all cameras so we can use the VR camera instead
+			tiles.cameras.forEach( c => tiles.deleteCamera( camera ) );
+
+			const currCamera = renderer.xr.getCamera( camera );
+			tiles.setCamera( currCamera );
+
+			const leftCam = currCamera.cameras[ 0 ];
+			if ( leftCam ) {
+
+				tiles.setResolution( currCamera, leftCam.viewport.z, leftCam.viewport.w );
+
+			}
 
-	renderer.setAnimationLoop( render );
+			xrSession = renderer.xr.getSession();
+
+		}
+
+	} else {
+
+		// Reset default camera (exiting WebXR session)
+		if ( xrSession !== null ) {
+
+			tiles.cameras.forEach( c => tiles.deleteCamera( camera ) );
+
+			tiles.setCamera( camera );
+			tiles.setResolutionFromRenderer( camera, renderer );
+
+			camera.position.set( 0, 1, 0 );
+
+			xrSession = null;
+
+		}
+
+	}
 
 }
 
+function handleTasks() {
+
+	if ( tasks.length < 1 ) return;
+
+	const tt = tasks;
+	let tlen = tt.length;
 
-function render() {
+	for ( let t = 0; t < tlen; t ++ ) tt[ t ]();
+	tasks = [];
 
-	requestAnimationFrame( animate );
+}
+
+function frame() {
 
 	grid.visible = params.displayGrid;
 
@@ -249,32 +303,14 @@ function render() {
 
 	}
 
-	// remove all cameras so we can use the VR camera instead
-	tiles.cameras.forEach( c => tiles.deleteCamera( camera ) );
-
-	// get the XR camera with a combined frustum for culling
-	if ( renderer.xr.isPresenting ) {
-
-		const currCamera = renderer.xr.getCamera( camera );
-		tiles.setCamera( currCamera );
-
-		const leftCam = currCamera.cameras[ 0 ];
-		if ( leftCam ) {
-
-			tiles.setResolution( currCamera, leftCam.viewport.z, leftCam.viewport.w );
-
-		}
-
-	} else {
+	// We check for tiles camera setup (default and XR sessions)
+	handleCamera();
 
-		tiles.setCamera( camera );
-		tiles.setResolutionFromRenderer( camera, renderer );
-
-	}
+	// We handle pending tasks
+	handleTasks();
 
 	tiles.update();
 
-
 	if ( controller.controllerActive ) {
 
 		const { ray } = raycaster;