diff --git a/examples/js/vr/WebVR.js b/examples/js/vr/WebVR.js index 91068539c46397ce1dbc295af9aa16540b01de26..db6fc9fe6bda62e2e359d61deb194b7521f26c9f 100644 --- a/examples/js/vr/WebVR.js +++ b/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'; diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js index 5832dcd64e3410702dc15d17bcf8fe37e8b5e5b3..8eecce872304a320f485c00cd3e90a3148bf0f13 100644 --- a/src/renderers/WebGLRenderer.js +++ b/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 ); }; diff --git a/src/renderers/webgl/WebGLAnimation.js b/src/renderers/webgl/WebGLAnimation.js new file mode 100644 index 0000000000000000000000000000000000000000..55629006c1a62b5e6a2b40abf35a6025dd0ea345 --- /dev/null +++ b/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 }; diff --git a/src/renderers/webvr/WebVRManager.js b/src/renderers/webvr/WebVRManager.js index f07f6c93a957616cebe9745a4345437a29aea6de..86100e14f42777805a86e92f6b60f745feacaca3 100644 --- a/src/renderers/webvr/WebVRManager.js +++ b/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 }; diff --git a/src/renderers/webvr/WebXRManager.js b/src/renderers/webvr/WebXRManager.js index e03566ae6ef5374de78b897daf22dc7950a8f05f..208fbe32f985a7f299fef8947dc72bc77f725676 100644 --- a/src/renderers/webvr/WebXRManager.js +++ b/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 () {}; }