diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js index 71ccc870e88a5d816fa793eae3803e639a732bcd..518a1620a4f196b3730807f94bc58203fb13b871 100644 --- a/src/renderers/WebGLRenderer.js +++ b/src/renderers/WebGLRenderer.js @@ -28,6 +28,7 @@ import { WebGLTextures } from './webgl/WebGLTextures'; import { WebGLProperties } from './webgl/WebGLProperties'; import { WebGLState } from './webgl/WebGLState'; import { WebGLCapabilities } from './webgl/WebGLCapabilities'; +import { WebVRManager } from './webvr/WebVRManager'; import { BufferGeometry } from '../core/BufferGeometry'; import { WebGLExtensions } from './webgl/WebGLExtensions'; import { Vector3 } from '../math/Vector3'; @@ -295,6 +296,7 @@ function WebGLRenderer( parameters ) { var programCache = new WebGLPrograms( this, capabilities ); var lightCache = new WebGLLights(); var renderLists = new WebGLRenderLists(); + var vr = new WebVRManager( this ); this.info.programs = programCache.programs; @@ -345,6 +347,7 @@ function WebGLRenderer( parameters ) { this.properties = properties; this.renderLists = renderLists; this.state = state; + this.vr = vr; // shadow map @@ -1082,6 +1085,20 @@ function WebGLRenderer( parameters ) { // Rendering + this.animate = function ( callback ) { + + function onFrame() { + + callback(); + + ( vr.getDevice() || window ).requestAnimationFrame( onFrame ); + + } + + ( vr.getDevice() || window ).requestAnimationFrame( onFrame ); + + }; + this.render = function ( scene, camera, renderTarget, forceClear ) { if ( ! ( camera && camera.isCamera ) ) { @@ -1107,6 +1124,12 @@ function WebGLRenderer( parameters ) { if ( camera.parent === null ) camera.updateMatrixWorld(); + if ( vr.enabled ) { + + camera = vr.getCamera( camera ); + + } + _projScreenMatrix.multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse ); _frustum.setFromMatrix( _projScreenMatrix ); diff --git a/examples/js/vr/WebVRCamera.js b/src/renderers/webvr/WebVRManager.js similarity index 60% rename from examples/js/vr/WebVRCamera.js rename to src/renderers/webvr/WebVRManager.js index 0f98ec7c3c0068c368d2366aa4b0ae97604fa27c..ec71e5d0d1c00a1585bffa203310d474e6f84f3a 100644 --- a/examples/js/vr/WebVRCamera.js +++ b/src/renderers/webvr/WebVRManager.js @@ -2,10 +2,11 @@ * @author mrdoob / http://mrdoob.com/ */ -THREE.WebVRCamera = function ( display, renderer ) { +function WebVRManager( renderer ) { var scope = this; + var device = null; var frameData = null; if ( 'VRFrameData' in window ) { @@ -22,7 +23,7 @@ THREE.WebVRCamera = function ( display, renderer ) { cameraR.bounds = new THREE.Vector4( 0.5, 0.0, 0.5, 1.0 ); cameraR.layers.enable( 2 ); - var matrixWorldInverse = new THREE.Matrix4(); + var cameraVR = new THREE.ArrayCamera( [ cameraL, cameraR ] ); // @@ -30,9 +31,9 @@ THREE.WebVRCamera = function ( display, renderer ) { function onVRDisplayPresentChange() { - if ( display.isPresenting ) { + if ( device.isPresenting ) { - var eyeParameters = display.getEyeParameters( 'left' ); + var eyeParameters = device.getEyeParameters( 'left' ); var renderWidth = eyeParameters.renderWidth; var renderHeight = eyeParameters.renderHeight; @@ -42,12 +43,8 @@ THREE.WebVRCamera = function ( display, renderer ) { renderer.setPixelRatio( 1 ); renderer.setSize( renderWidth * 2, renderHeight, false ); - scope.enabled = true; - } else if ( scope.enabled ) { - scope.enabled = false; - renderer.setPixelRatio( currentPixelRatio ); renderer.setSize( currentSize.width, currentSize.height, true ); @@ -59,48 +56,67 @@ THREE.WebVRCamera = function ( display, renderer ) { // - THREE.ArrayCamera.call( this, [ cameraL, cameraR ] ); + this.enabled = false; - // + this.getDevice = function () { - this.onBeforeRender = function () { + return device; - display.depthNear = scope.near; - display.depthFar = scope.far; + }; - display.getFrameData( frameData ); + this.setDevice = function ( value ) { - // + if ( value !== undefined ) device = value; - var pose = frameData.pose; + }; - if ( pose.orientation !== null ) { + this.getCamera = function ( camera ) { - scope.quaternion.fromArray( pose.orientation ); + if ( device === null ) return camera; - } + device.depthNear = camera.near; + device.depthFar = camera.far; + + device.getFrameData( frameData ); + + // + + var pose = frameData.pose; if ( pose.position !== null ) { - scope.position.fromArray( pose.position ); + camera.position.fromArray( pose.position ); } else { - scope.position.set( 0, 0, 0 ); + camera.position.set( 0, 0, 0 ); } + if ( pose.orientation !== null ) { + + camera.quaternion.fromArray( pose.orientation ); + + } + + camera.updateMatrixWorld(); + + if ( device.isPresenting === false ) return camera; + // + cameraVR.matrixWorld.copy( camera.matrixWorld ); + cameraVR.matrixWorldInverse.copy( camera.matrixWorldInverse ); + cameraL.matrixWorldInverse.fromArray( frameData.leftViewMatrix ); cameraR.matrixWorldInverse.fromArray( frameData.rightViewMatrix ); - if ( scope.parent !== null ) { + var parent = camera.parent; - matrixWorldInverse.getInverse( scope.parent.matrixWorld ); + if ( parent !== null ) { - cameraL.matrixWorldInverse.multiply( matrixWorldInverse ); - cameraR.matrixWorldInverse.multiply( matrixWorldInverse ); + cameraL.matrixWorldInverse.multiply( parent.matrixWorldInverse ); + cameraR.matrixWorldInverse.multiply( parent.matrixWorldInverse ); } @@ -110,11 +126,11 @@ THREE.WebVRCamera = function ( display, renderer ) { // HACK @mrdoob // https://github.com/w3c/webvr/issues/203 - scope.projectionMatrix.copy( cameraL.projectionMatrix ); + cameraVR.projectionMatrix.copy( cameraL.projectionMatrix ); // - var layers = display.getLayers(); + var layers = device.getLayers(); if ( layers.length ) { @@ -134,20 +150,10 @@ THREE.WebVRCamera = function ( display, renderer ) { } - }; - - this.onAfterRender = function () { - - if ( display.isPresenting ) display.submitFrame(); + return cameraVR; }; -}; - -THREE.WebVRCamera.prototype = Object.assign( Object.create( THREE.ArrayCamera.prototype ), { - - constructor: THREE.WebVRCamera, - - isWebVRCamera: true +} -} ); +export { WebVRManager };