Skip to content

Commit a3ac58e

Browse files
committed
Make vrdisplayactivate driven enter-vr path more robust
1 parent 789eed3 commit a3ac58e

File tree

5 files changed

+28
-29
lines changed

5 files changed

+28
-29
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@
5050
"promise-polyfill": "^3.1.0",
5151
"style-attr": "^1.0.2",
5252
"super-animejs": "^3.0.0",
53-
"super-three": "^0.102.1",
53+
"super-three": "^0.102.2",
5454
"three-bmfont-text": "^2.1.0",
5555
"webvr-polyfill": "^0.10.10"
5656
},

src/core/scene/a-scene.js

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ module.exports.AScene = registerElement('a-scene', {
3838
prototype: Object.create(AEntity.prototype, {
3939
createdCallback: {
4040
value: function () {
41+
this.clock = new THREE.Clock();
4142
this.isIOS = isIOS;
4243
this.isMobile = isMobile;
4344
this.hasWebXR = isWebXRAvailable;
@@ -265,8 +266,8 @@ module.exports.AScene = registerElement('a-scene', {
265266
// Has VR.
266267
if (this.checkHeadsetConnected() || this.isMobile) {
267268
vrDisplay = utils.device.getVRDisplay();
268-
vrManager.setDevice(vrDisplay);
269269
vrManager.enabled = true;
270+
vrManager.setDevice(vrDisplay);
270271

271272
if (this.hasWebXR) {
272273
// XR API.
@@ -286,17 +287,12 @@ module.exports.AScene = registerElement('a-scene', {
286287
enterVRSuccess();
287288
});
288289
} else {
289-
// WebVR API.
290-
if (vrDisplay.isPresenting) {
291-
enterVRSuccess();
292-
return Promise.resolve();
293-
}
294-
295290
var rendererSystem = this.getAttribute('renderer');
296291
var presentationAttributes = {
297292
highRefreshRate: rendererSystem.highRefreshRate,
298293
foveationLevel: rendererSystem.foveationLevel
299294
};
295+
300296
return vrDisplay.requestPresent([{
301297
source: this.canvas,
302298
attributes: presentationAttributes
@@ -326,6 +322,8 @@ module.exports.AScene = registerElement('a-scene', {
326322
if (!self.isMobile && !self.checkHeadsetConnected()) {
327323
requestFullscreen(self.canvas);
328324
}
325+
326+
self.renderer.setAnimationLoop(self.render);
329327
self.resize();
330328
}
331329

@@ -624,19 +622,23 @@ module.exports.AScene = registerElement('a-scene', {
624622
}
625623

626624
this.addEventListener('loaded', function () {
625+
var renderer = this.renderer;
626+
var vrManager = this.renderer.vr;
627627
AEntity.prototype.play.call(this); // .play() *before* render.
628628

629629
if (sceneEl.renderStarted) { return; }
630-
631630
sceneEl.resize();
632631

633632
// Kick off render loop.
634633
if (sceneEl.renderer) {
635634
if (window.performance) { window.performance.mark('render-started'); }
636-
sceneEl.clock = new THREE.Clock();
637635
loadingScreen.remove();
638-
sceneEl.renderer.setAnimationLoop(this.render);
639-
sceneEl.render();
636+
if (utils.device.getVRDisplay().isPresenting) {
637+
vrManager.setDevice(utils.device.getVRDisplay());
638+
vrManager.enabled = true;
639+
sceneEl.enterVR();
640+
}
641+
renderer.setAnimationLoop(this.render);
640642
sceneEl.renderStarted = true;
641643
sceneEl.emit('renderstart');
642644
}

src/core/scene/loadingScreen.js

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,22 +9,6 @@ var getSceneCanvasSize;
99
var ATTR_NAME = 'loading-screen';
1010
var LOADER_TITLE_CLASS = 'a-loader-title';
1111

12-
// It catches vrdisplayactivate early to ensure we can enter VR mode after the scene loads.
13-
window.addEventListener('vrdisplayactivate', function () {
14-
var vrManager = sceneEl.renderer.vr;
15-
var vrDisplay;
16-
17-
// WebXR takes priority if available.
18-
if (navigator.xr) { return; }
19-
20-
vrDisplay = utils.device.getVRDisplay();
21-
vrManager.setDevice(vrDisplay);
22-
vrManager.enabled = true;
23-
if (!vrDisplay.isPresenting) {
24-
return vrDisplay.requestPresent([{source: sceneEl.canvas}]).then(function () {}, function () {});
25-
}
26-
});
27-
2812
module.exports.setup = function setup (el, getCanvasSize) {
2913
sceneEl = el;
3014
getSceneCanvasSize = getCanvasSize;

src/utils/device.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,17 @@ var error = require('debug')('device:error');
22

33
var vrDisplay;
44

5+
// It catches vrdisplayactivate early to ensure we can enter VR mode after the scene loads.
6+
window.addEventListener('vrdisplayactivate', function (evt) {
7+
var canvasEl;
8+
// WebXR takes priority if available.
9+
if (navigator.xr) { return; }
10+
canvasEl = document.createElement('canvas');
11+
vrDisplay = evt.display;
12+
// Request present immediately. a-scene will be allowed to enter VR without user gesture.
13+
vrDisplay.requestPresent([{source: canvasEl}]).then(function () {}, function () {});
14+
});
15+
516
// Support both WebVR and WebXR APIs.
617
if (navigator.xr) {
718
navigator.xr.requestDevice().then(function (device) {

tests/core/scene/a-scene.test.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,9 @@ suite('a-scene (without renderer)', function () {
141141
getDevice: function () {},
142142
setDevice: function () {},
143143
setPoseTarget: function () {}
144-
}
144+
},
145+
getContext: function () { return undefined; },
146+
setAnimationLoop: function () {}
145147
};
146148

147149
// mock camera

0 commit comments

Comments
 (0)