提交 8f2c2fa0 编写于 作者: M Mr.doob

Added basic WebXR support.

上级 bbfbe98c
......@@ -9,7 +9,7 @@ var WEBVR = {
createButton: function ( renderer ) {
function showEnterVR( display ) {
function showEnterVR( device ) {
button.style.display = '';
......@@ -24,11 +24,29 @@ var WEBVR = {
button.onclick = function () {
display.isPresenting ? display.exitPresent() : display.requestPresent( [ { source: renderer.domElement } ] );
if ( 'xr' in navigator ) {
device.requestSession( { exclusive: true } ).then( function ( session ) {
renderer.vr.setSession( session );
session.addEventListener( 'end', function ( event ) {
renderer.vr.setSession( null );
} );
} );
} else {
device.isPresenting ? device.exitPresent() : device.requestPresent( [ { source: renderer.domElement } ] );
}
};
renderer.vr.setDevice( display );
renderer.vr.setDevice( device );
}
......@@ -68,7 +86,31 @@ var WEBVR = {
}
if ( 'getVRDisplays' in navigator ) {
var isWebXR = false;
if ( 'xr' in navigator ) {
isWebXR = true;
var button = document.createElement( 'button' );
button.style.display = 'none';
stylizeElement( button );
navigator.xr.requestDevice().then( function ( device ) {
device.supportsSession( { exclusive: true } ).then( function () {
showEnterVR( device );
button.textContent = 'ENTER XR'; // TODO
} ).catch( showVRNotFound );
} ).catch( showVRNotFound );
return button;
} else if ( 'getVRDisplays' in navigator ) {
var button = document.createElement( 'button' );
button.style.display = 'none';
......
......@@ -42,6 +42,7 @@ import { WebGLTextures } from './webgl/WebGLTextures.js';
import { WebGLUniforms } from './webgl/WebGLUniforms.js';
import { WebGLUtils } from './webgl/WebGLUtils.js';
import { WebVRManager } from './webvr/WebVRManager.js';
import { WebXRManager } from './webvr/WebXRManager.js';
/**
* @author supereggbert / http://www.paulbrunt.co.uk/
......@@ -288,7 +289,7 @@ function WebGLRenderer( parameters ) {
// vr
var vr = new WebVRManager( _this );
var vr = ( 'xr' in navigator ) ? new WebXRManager( _gl ) : new WebVRManager( _this );
this.vr = vr;
......@@ -353,9 +354,7 @@ function WebGLRenderer( parameters ) {
this.setSize = function ( width, height, updateStyle ) {
var device = vr.getDevice();
if ( device && device.isPresenting ) {
if ( vr.isPresenting() ) {
console.warn( 'THREE.WebGLRenderer: Can\'t change size while VR device is presenting.' );
return;
......@@ -1037,11 +1036,9 @@ function WebGLRenderer( parameters ) {
function requestAnimationLoopFrame() {
var device = vr.getDevice();
if ( device && device.isPresenting ) {
if ( vr.isPresenting() ) {
device.requestAnimationFrame( animationLoop );
vr.requestAnimationFrame( animationLoop );
} else {
......@@ -1388,14 +1385,22 @@ function WebGLRenderer( parameters ) {
if ( object.layers.test( camera2.layers ) ) {
var bounds = camera2.bounds;
if ( 'viewport' in camera2 ) { // XR
state.viewport( _currentViewport.copy( camera2.viewport ) );
} else {
var bounds = camera2.bounds;
var x = bounds.x * _width;
var y = bounds.y * _height;
var width = bounds.z * _width;
var height = bounds.w * _height;
var x = bounds.x * _width;
var y = bounds.y * _height;
var width = bounds.z * _width;
var height = bounds.w * _height;
state.viewport( _currentViewport.set( x, y, width, height ).multiplyScalar( _pixelRatio ) );
state.viewport( _currentViewport.set( x, y, width, height ).multiplyScalar( _pixelRatio ) );
}
renderObject( object, scene, camera2, geometry, material, group );
......
......@@ -3,8 +3,8 @@
*/
import { Matrix4 } from '../../math/Matrix4.js';
import { Vector4 } from '../../math/Vector4.js';
import { Vector3 } from '../../math/Vector3.js';
import { Vector4 } from '../../math/Vector4.js';
import { Quaternion } from '../../math/Quaternion.js';
import { ArrayCamera } from '../../cameras/ArrayCamera.js';
import { PerspectiveCamera } from '../../cameras/PerspectiveCamera.js';
......@@ -226,6 +226,14 @@ function WebVRManager( renderer ) {
};
this.isPresenting = isPresenting;
this.requestAnimationFrame = function ( callback ) {
device.requestAnimationFrame( callback );
};
this.submitFrame = function () {
if ( isPresenting() ) device.submitFrame();
......
/**
* @author mrdoob / http://mrdoob.com/
*/
import { Matrix4 } from '../../math/Matrix4.js';
import { Vector4 } from '../../math/Vector4.js';
import { Vector3 } from '../../math/Vector3.js';
import { Quaternion } from '../../math/Quaternion.js';
import { ArrayCamera } from '../../cameras/ArrayCamera.js';
import { PerspectiveCamera } from '../../cameras/PerspectiveCamera.js';
function WebXRManager( gl ) {
var scope = this;
var device = null;
var session = null;
var frameOfRef = null;
var isExclusive = false;
var pose = null;
function isPresenting() {
return session !== null && frameOfRef !== 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.getDevice = function () {
return device;
};
this.setDevice = function ( value ) {
if ( value !== undefined ) device = value;
gl.setCompatibleXRDevice( value );
};
this.setSession = function ( value ) {
session = value;
if ( session !== null ) {
session.baseLayer = new XRWebGLLayer( session, gl );
session.requestFrameOfReference( 'stage' ).then( function ( value ) {
frameOfRef = value;
isExclusive = session.exclusive;
console.log( 0 );
} );
}
};
this.getCamera = function ( camera ) {
return isPresenting() ? cameraVR : camera;
};
this.isPresenting = isPresenting;
this.requestAnimationFrame = function ( callback ) {
console.log( 1 );
function onFrame( time, frame ) {
pose = frame.getDevicePose( frameOfRef );
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.projectionMatrix.fromArray( view.projectionMatrix );
camera.matrixWorldInverse.fromArray( viewMatrix );
camera.matrixWorld.getInverse( camera.matrixWorldInverse );
camera.viewport.set( viewport.x, viewport.y, viewport.width, viewport.height );
if ( i === 0 ) {
cameraVR.matrixWorld.copy( camera.matrixWorld );
cameraVR.matrixWorldInverse.copy( camera.matrixWorldInverse );
// HACK (mrdoob)
// https://github.com/w3c/webvr/issues/203
cameraVR.projectionMatrix.copy( camera.projectionMatrix );
}
}
gl.bindFramebuffer( gl.FRAMEBUFFER, session.baseLayer.framebuffer );
callback();
}
session.requestAnimationFrame( onFrame );
};
this.submitFrame = function () {
// if ( device && device.isPresenting ) device.submitFrame();
};
}
export { WebXRManager };
......@@ -5,3 +5,4 @@ var exports;
var performance;
var createImageBitmap;
var WebGL2RenderingContext;
var XRWebGLLayer;
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册