| |
| |
| |
|
|
| import { Group } from '../../objects/Group.js'; |
| import { Matrix4 } from '../../math/Matrix4.js'; |
| import { Vector4 } from '../../math/Vector4.js'; |
| import { ArrayCamera } from '../../cameras/ArrayCamera.js'; |
| import { PerspectiveCamera } from '../../cameras/PerspectiveCamera.js'; |
| import { WebGLAnimation } from '../webgl/WebGLAnimation.js'; |
| import { setProjectionFromUnion } from './WebVRUtils.js'; |
|
|
| function WebXRManager( renderer ) { |
|
|
| var gl = renderer.context; |
|
|
| var device = null; |
| var session = null; |
|
|
| var framebufferScaleFactor = 1.0; |
|
|
| var frameOfReference = null; |
| var frameOfReferenceType = 'stage'; |
|
|
| var pose = null; |
|
|
| var controllers = []; |
| var inputSources = []; |
|
|
| function isPresenting() { |
|
|
| return session !== null && frameOfReference !== null; |
|
|
| } |
|
|
| |
|
|
| var cameraL = new PerspectiveCamera(); |
| cameraL.layers.enable( 1 ); |
| cameraL.viewport = new Vector4(); |
|
|
| var cameraR = new PerspectiveCamera(); |
| cameraR.layers.enable( 2 ); |
| cameraR.viewport = new Vector4(); |
|
|
| var cameraVR = new ArrayCamera( [ cameraL, cameraR ] ); |
| cameraVR.layers.enable( 1 ); |
| cameraVR.layers.enable( 2 ); |
|
|
| |
|
|
| this.enabled = false; |
|
|
| this.getController = function ( id ) { |
|
|
| var controller = controllers[ id ]; |
|
|
| if ( controller === undefined ) { |
|
|
| controller = new Group(); |
| controller.matrixAutoUpdate = false; |
| controller.visible = false; |
|
|
| controllers[ id ] = controller; |
|
|
| } |
|
|
| return controller; |
|
|
| }; |
|
|
| this.getDevice = function () { |
|
|
| return device; |
|
|
| }; |
|
|
| this.setDevice = function ( value ) { |
|
|
| if ( value !== undefined ) device = value; |
| if ( value instanceof XRDevice ) gl.setCompatibleXRDevice( value ); |
|
|
| }; |
|
|
| |
|
|
| function onSessionEvent( event ) { |
|
|
| var controller = controllers[ inputSources.indexOf( event.inputSource ) ]; |
| if ( controller ) controller.dispatchEvent( { type: event.type } ); |
|
|
| } |
|
|
| function onSessionEnd() { |
|
|
| renderer.setFramebuffer( null ); |
| renderer.setRenderTarget( renderer.getRenderTarget() ); |
| animation.stop(); |
|
|
| } |
|
|
| this.setFramebufferScaleFactor = function ( value ) { |
|
|
| framebufferScaleFactor = value; |
|
|
| }; |
|
|
| this.setFrameOfReferenceType = function ( value ) { |
|
|
| frameOfReferenceType = value; |
|
|
| }; |
|
|
| this.setSession = function ( value ) { |
|
|
| session = value; |
|
|
| if ( session !== null ) { |
|
|
| session.addEventListener( 'select', onSessionEvent ); |
| session.addEventListener( 'selectstart', onSessionEvent ); |
| session.addEventListener( 'selectend', onSessionEvent ); |
| session.addEventListener( 'end', onSessionEnd ); |
|
|
| session.baseLayer = new XRWebGLLayer( session, gl, { framebufferScaleFactor: framebufferScaleFactor } ); |
| session.requestFrameOfReference( frameOfReferenceType ).then( function ( value ) { |
|
|
| frameOfReference = value; |
|
|
| renderer.setFramebuffer( session.baseLayer.framebuffer ); |
|
|
| animation.setContext( session ); |
| animation.start(); |
|
|
| } ); |
|
|
| |
|
|
| inputSources = session.getInputSources(); |
|
|
| session.addEventListener( 'inputsourceschange', function () { |
|
|
| inputSources = session.getInputSources(); |
| console.log( inputSources ); |
|
|
| for ( var i = 0; i < controllers.length; i ++ ) { |
|
|
| var controller = controllers[ i ]; |
| controller.userData.inputSource = inputSources[ i ]; |
|
|
| } |
|
|
| } ); |
|
|
| } |
|
|
| }; |
|
|
| function updateCamera( camera, parent ) { |
|
|
| if ( parent === null ) { |
|
|
| camera.matrixWorld.copy( camera.matrix ); |
|
|
| } else { |
|
|
| camera.matrixWorld.multiplyMatrices( parent.matrixWorld, camera.matrix ); |
|
|
| } |
|
|
| camera.matrixWorldInverse.getInverse( camera.matrixWorld ); |
|
|
| } |
|
|
| this.getCamera = function ( camera ) { |
|
|
| if ( isPresenting() ) { |
|
|
| var parent = camera.parent; |
| var cameras = cameraVR.cameras; |
|
|
| updateCamera( cameraVR, parent ); |
|
|
| for ( var i = 0; i < cameras.length; i ++ ) { |
|
|
| updateCamera( cameras[ i ], parent ); |
|
|
| } |
|
|
| |
|
|
| camera.matrixWorld.copy( cameraVR.matrixWorld ); |
|
|
| var children = camera.children; |
|
|
| for ( var i = 0, l = children.length; i < l; i ++ ) { |
|
|
| children[ i ].updateMatrixWorld( true ); |
|
|
| } |
|
|
| setProjectionFromUnion( cameraVR, cameraL, cameraR ); |
|
|
| return cameraVR; |
|
|
| } |
|
|
| return camera; |
|
|
| }; |
|
|
| this.isPresenting = isPresenting; |
|
|
| |
|
|
| var onAnimationFrameCallback = null; |
|
|
| function onAnimationFrame( time, frame ) { |
|
|
| pose = frame.getDevicePose( frameOfReference ); |
|
|
| if ( pose !== null ) { |
|
|
| var layer = session.baseLayer; |
| var views = frame.views; |
|
|
| for ( var i = 0; i < views.length; i ++ ) { |
|
|
| var view = views[ i ]; |
| var viewport = layer.getViewport( view ); |
| var viewMatrix = pose.getViewMatrix( view ); |
|
|
| var camera = cameraVR.cameras[ i ]; |
| camera.matrix.fromArray( viewMatrix ).getInverse( camera.matrix ); |
| camera.projectionMatrix.fromArray( view.projectionMatrix ); |
| camera.viewport.set( viewport.x, viewport.y, viewport.width, viewport.height ); |
|
|
| if ( i === 0 ) { |
|
|
| cameraVR.matrix.copy( camera.matrix ); |
|
|
| } |
|
|
| } |
|
|
| } |
|
|
| |
|
|
| for ( var i = 0; i < controllers.length; i ++ ) { |
|
|
| var controller = controllers[ i ]; |
|
|
| var inputSource = inputSources[ i ]; |
|
|
| if ( inputSource ) { |
|
|
| var inputPose = frame.getInputPose( inputSource, frameOfReference ); |
|
|
| if ( inputPose !== null ) { |
|
|
| if ( 'targetRay' in inputPose ) { |
|
|
| controller.matrix.elements = inputPose.targetRay.transformMatrix; |
|
|
| } else if ( 'pointerMatrix' in inputPose ) { |
|
|
| |
|
|
| controller.matrix.elements = inputPose.pointerMatrix; |
|
|
| } |
|
|
| controller.matrix.decompose( controller.position, controller.rotation, controller.scale ); |
| controller.visible = true; |
|
|
| continue; |
|
|
| } |
|
|
| } |
|
|
| controller.visible = false; |
|
|
| } |
|
|
| if ( onAnimationFrameCallback ) onAnimationFrameCallback( time ); |
|
|
| } |
|
|
| var animation = new WebGLAnimation(); |
| animation.setAnimationLoop( onAnimationFrame ); |
|
|
| this.setAnimationLoop = function ( callback ) { |
|
|
| onAnimationFrameCallback = callback; |
|
|
| }; |
|
|
| this.dispose = function () {}; |
|
|
| |
|
|
| this.getStandingMatrix = function () { |
|
|
| console.warn( 'THREE.WebXRManager: getStandingMatrix() is no longer needed.' ); |
| return new Matrix4(); |
|
|
| }; |
|
|
| this.submitFrame = function () {}; |
|
|
| } |
|
|
| export { WebXRManager }; |
|
|