Pārlūkot izejas kodu

WebGLRenderer: Added WebGLAnimation.

Mr.doob 7 gadi atpakaļ
vecāks
revīzija
06903c44a2

+ 2 - 0
examples/js/vr/WebVR.js

@@ -49,6 +49,8 @@ var WEBVR = {
 
 			function onSessionEnded( event ) {
 
+				currentSession.removeEventListener( 'end', onSessionEnded );
+
 				renderer.vr.setSession( null );
 				button.textContent = 'ENTER XR';
 

+ 12 - 39
src/renderers/WebGLRenderer.js

@@ -20,6 +20,7 @@ import { UniformsLib } from './shaders/UniformsLib.js';
 import { UniformsUtils } from './shaders/UniformsUtils.js';
 import { Vector3 } from '../math/Vector3.js';
 import { Vector4 } from '../math/Vector4.js';
+import { WebGLAnimation } from './webgl/WebGLAnimation.js';
 import { WebGLAttributes } from './webgl/WebGLAttributes.js';
 import { WebGLBackground } from './webgl/WebGLBackground.js';
 import { WebGLBufferRenderer } from './webgl/WebGLBufferRenderer.js';
@@ -1015,53 +1016,25 @@ function WebGLRenderer( parameters ) {
 
 	// Animation Loop
 
-	var isAnimating = false;
-	var onAnimationFrame = null;
+	var onAnimationFrameCallback = null;
 
-	function startAnimation() {
+	function onAnimationFrame() {
 
-		if ( isAnimating ) return;
-
-		requestAnimationLoopFrame();
-
-		isAnimating = true;
-
-	}
-
-	function stopAnimation() {
-
-		isAnimating = false;
+		if ( vr.isPresenting() ) return;
+		if ( onAnimationFrameCallback ) onAnimationFrameCallback();
 
 	}
 
-	function requestAnimationLoopFrame() {
-
-		if ( vr.isPresenting() ) {
-
-			vr.requestAnimationFrame( animationLoop );
-
-		} else {
-
-			window.requestAnimationFrame( animationLoop );
-
-		}
-
-	}
-
-	function animationLoop( time ) {
-
-		if ( isAnimating === false ) return;
-
-		onAnimationFrame( time );
-
-		requestAnimationLoopFrame();
-
-	}
+	var animation = new WebGLAnimation();
+	animation.setAnimationLoop( onAnimationFrame );
+	animation.setContext( window );
 
 	this.setAnimationLoop = function ( callback ) {
 
-		onAnimationFrame = callback;
-		onAnimationFrame !== null ? startAnimation() : stopAnimation();
+		onAnimationFrameCallback = callback;
+		animation.start();
+
+		vr.setAnimationLoop( callback );
 
 	};
 

+ 56 - 0
src/renderers/webgl/WebGLAnimation.js

@@ -0,0 +1,56 @@
+/**
+ * @author mrdoob / http://mrdoob.com/
+ */
+
+function WebGLAnimation() {
+
+	var context = null;
+	var isAnimating = false;
+	var animationLoop = null;
+
+	function onAnimationFrame( time, frame ) {
+
+		if ( isAnimating === false ) return;
+
+		animationLoop( time, frame );
+
+		context.requestAnimationFrame( onAnimationFrame );
+
+	}
+
+	return {
+
+		start: function () {
+
+			if ( isAnimating === true ) return;
+			if ( animationLoop === null ) return;
+
+			context.requestAnimationFrame( onAnimationFrame );
+
+			isAnimating = true;
+
+		},
+
+		stop: function () {
+
+			isAnimating = false;
+
+		},
+
+		setAnimationLoop: function ( callback ) {
+
+			animationLoop = callback;
+
+		},
+
+		setContext: function ( value ) {
+
+			context = value;
+
+		}
+
+	}
+
+}
+
+export { WebGLAnimation };

+ 21 - 2
src/renderers/webvr/WebVRManager.js

@@ -8,6 +8,7 @@ import { Vector4 } from '../../math/Vector4.js';
 import { Quaternion } from '../../math/Quaternion.js';
 import { ArrayCamera } from '../../cameras/ArrayCamera.js';
 import { PerspectiveCamera } from '../../cameras/PerspectiveCamera.js';
+import { WebGLAnimation } from '../webgl/WebGLAnimation.js';
 
 function WebVRManager( renderer ) {
 
@@ -67,10 +68,14 @@ function WebVRManager( renderer ) {
 
 			renderer.setDrawingBufferSize( renderWidth * 2, renderHeight, 1 );
 
+			animation.start();
+
 		} else if ( scope.enabled ) {
 
 			renderer.setDrawingBufferSize( currentSize.width, currentSize.height, currentPixelRatio );
 
+			animation.stop();
+
 		}
 
 	}
@@ -90,6 +95,8 @@ function WebVRManager( renderer ) {
 
 		if ( value !== undefined ) device = value;
 
+		animation.setContext( value );
+
 	};
 
 	this.setPoseTarget = function ( object ) {
@@ -228,9 +235,13 @@ function WebVRManager( renderer ) {
 
 	this.isPresenting = isPresenting;
 
-	this.requestAnimationFrame = function ( callback ) {
+	// Animation Loop
+
+	var animation = new WebGLAnimation();
+
+	this.setAnimationLoop = function ( callback ) {
 
-		device.requestAnimationFrame( callback );
+		animation.setAnimationLoop( callback );
 
 	};
 
@@ -250,6 +261,14 @@ function WebVRManager( renderer ) {
 
 	};
 
+	// DEPRECATED
+
+	this.requestAnimationFrame = function ( callback ) {
+
+		// device.requestAnimationFrame( callback );
+
+	};
+
 }
 
 export { WebVRManager };

+ 47 - 25
src/renderers/webvr/WebXRManager.js

@@ -8,6 +8,7 @@ import { Vector3 } from '../../math/Vector3.js';
 import { Quaternion } from '../../math/Quaternion.js';
 import { ArrayCamera } from '../../cameras/ArrayCamera.js';
 import { PerspectiveCamera } from '../../cameras/PerspectiveCamera.js';
+import { WebGLAnimation } from '../webgl/WebGLAnimation.js';
 
 function WebXRManager( gl ) {
 
@@ -59,18 +60,30 @@ function WebXRManager( gl ) {
 
 	};
 
+	//
+
 	this.setSession = function ( value ) {
 
 		session = value;
 
 		if ( session !== null ) {
 
+			session.addEventListener( 'end', function () {
+
+				gl.bindFramebuffer( gl.FRAMEBUFFER, null );
+				animation.stop();
+
+			} );
+
 			session.baseLayer = new XRWebGLLayer( session, gl );
 			session.requestFrameOfReference( 'stage' ).then( function ( value ) {
 
 				frameOfRef = value;
 				isExclusive = session.exclusive;
 
+				animation.setContext( session );
+				animation.start();
+
 			} );
 
 		}
@@ -85,48 +98,55 @@ function WebXRManager( gl ) {
 
 	this.isPresenting = isPresenting;
 
-	this.requestAnimationFrame = function ( callback ) {
+	// Animation Loop
 
-		function onFrame( time, frame ) {
+	var onAnimationFrameCallback = null;
 
-			pose = frame.getDevicePose( frameOfRef );
+	function onAnimationFrame( time, frame ) {
 
-			var layer = session.baseLayer;
-			var views = frame.views;
+		pose = frame.getDevicePose( frameOfRef );
 
-			for ( var i = 0; i < views.length; i ++ ) {
+		var layer = session.baseLayer;
+		var views = frame.views;
 
-				var view = views[ i ];
-				var viewport = layer.getViewport( view );
-				var viewMatrix = pose.getViewMatrix( view );
+		for ( var i = 0; i < views.length; i ++ ) {
 
-				var camera = cameraVR.cameras[ i ];
-				camera.projectionMatrix.fromArray( view.projectionMatrix );
-				camera.matrixWorldInverse.fromArray( viewMatrix );
-				camera.matrixWorld.getInverse( camera.matrixWorldInverse );
-				camera.viewport.set( viewport.x, viewport.y, viewport.width, viewport.height );
+			var view = views[ i ];
+			var viewport = layer.getViewport( view );
+			var viewMatrix = pose.getViewMatrix( view );
 
-				if ( i === 0 ) {
+			var camera = cameraVR.cameras[ i ];
+			camera.projectionMatrix.fromArray( view.projectionMatrix );
+			camera.matrixWorldInverse.fromArray( viewMatrix );
+			camera.matrixWorld.getInverse( camera.matrixWorldInverse );
+			camera.viewport.set( viewport.x, viewport.y, viewport.width, viewport.height );
 
-					cameraVR.matrixWorld.copy( camera.matrixWorld );
-					cameraVR.matrixWorldInverse.copy( camera.matrixWorldInverse );
+			if ( i === 0 ) {
 
-					// HACK (mrdoob)
-					// https://github.com/w3c/webvr/issues/203
+				cameraVR.matrixWorld.copy( camera.matrixWorld );
+				cameraVR.matrixWorldInverse.copy( camera.matrixWorldInverse );
 
-					cameraVR.projectionMatrix.copy( camera.projectionMatrix );
+				// HACK (mrdoob)
+				// https://github.com/w3c/webvr/issues/203
 
-				}
+				cameraVR.projectionMatrix.copy( camera.projectionMatrix );
 
 			}
 
-			gl.bindFramebuffer( gl.FRAMEBUFFER, session.baseLayer.framebuffer );
+		}
 
-			callback();
+		gl.bindFramebuffer( gl.FRAMEBUFFER, session.baseLayer.framebuffer );
 
-		}
+		if ( onAnimationFrameCallback ) onAnimationFrameCallback();
+
+	}
 
-		session.requestAnimationFrame( onFrame );
+	var animation = new WebGLAnimation();
+	animation.setAnimationLoop( onAnimationFrame );
+
+	this.setAnimationLoop = function ( callback ) {
+
+		onAnimationFrameCallback = callback;
 
 	};
 
@@ -139,6 +159,8 @@ function WebXRManager( gl ) {
 
 	};
 
+	this.requestAnimationFrame = function () {};
+
 	this.submitFrame = function () {};
 
 }