Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 46 additions & 4 deletions examples/js/vr/WebVR.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ var WEBVR = {

createButton: function ( renderer ) {

function showEnterVR( display ) {
function showEnterVR( device ) {

button.style.display = '';

Expand All @@ -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 );

}

Expand Down Expand Up @@ -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';
Expand Down
33 changes: 19 additions & 14 deletions src/renderers/WebGLRenderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -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/
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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 {

Expand Down Expand Up @@ -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 );

Expand Down
10 changes: 9 additions & 1 deletion src/renderers/webvr/WebVRManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -226,6 +226,14 @@ function WebVRManager( renderer ) {

};

this.isPresenting = isPresenting;

this.requestAnimationFrame = function ( callback ) {

device.requestAnimationFrame( callback );

};

this.submitFrame = function () {

if ( isPresenting() ) device.submitFrame();
Expand Down
145 changes: 145 additions & 0 deletions src/renderers/webvr/WebXRManager.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
/**
* @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 );
Copy link
Collaborator

@takahirox takahirox May 2, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this console.log intended? Looks like for debugging or something.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, it's still work in progress. Just pushed it so @toji can take a look.


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 };
1 change: 1 addition & 0 deletions utils/build/externs.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ var exports;
var performance;
var createImageBitmap;
var WebGL2RenderingContext;
var XRWebGLLayer;