-
-
Notifications
You must be signed in to change notification settings - Fork 4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
handle vrdisplaypresentchange when triggering enter/exit VR outside aframe (fixes #2614) #2751
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks for tackling this. see my comments about the correct event name, filtering by the display
property in the event emitted, and handling setting A-Frame vr-mode
when vrdisplaypresentchange
on entering VR
src/core/scene/a-scene.js
Outdated
|
||
// Handler to exit VR (e.g., Oculus Browser back button). | ||
this.onVRPresentChange = bind(this.onVRPresentChange, this); | ||
window.addEventListener('onvrdisplaypresentchange', this.onVRPresentChange); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
need to drop the on
; the event is called vrdisplaypresentchange
src/core/scene/a-scene.js
Outdated
*/ | ||
onVRPresentChange: { | ||
value: function () { | ||
if (!this.is('vr-mode')) { return; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we have vr-mode
set if vrdisplaypresentchange
fires upon entering VR? if an A-Frame site wants to enter VR mode using the WebVR API directly, currently devs have to explicitly call $('a-scene').enterVR()
(when the user-gesture requirement is pref'd off, or in full-VR-only browsers such as the Oculus Browser).
currently, calling navigator.getVRDisplays().then(displays => displays[0].requestPresent([{source: $('canvas[data-aframe-canvas]')}])
doesn't properly set vr-mode
, etc., but it should.
this is actually necessary for properly entering VR mode upon page navigation (without the auto-enter-vr
component, which forces entering VR mode, not responding to the user's already being in VR mode).
there are cases where sites would want to handle entering VR mode by using the WebVR API directly, without needing to special case for A-Frame scenes vs. three.js scenes vs. others. examples: the WebVR Agent, a JS user script/bookmarklet, a WebExtension/Chrome browser extension, etc.
this will require a couple changes to the enterVR
method. specifically, instead of calling this.effect.requestPresent(…)
, we'll want to just check if if (this.checkHeadsetConnected() || this.isMobile)
and call enterVRSuccess()
.
src/core/scene/a-scene.js
Outdated
* on Oculus Browser. | ||
*/ | ||
onVRPresentChange: { | ||
value: function () { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this should check if (evt.display && evt.display.getLayers && evt.display.getLayers().indexOf(self.canvas) === -1) { return; }
so that VR mode isn't toggled for the wrong presentation event (examples: multiple A-Frame scenes on a page, or if there are two VR displays connected but the active A-Frame scene isn't the content being presented)
Thanks, updated. Didn't do the canvas checking here, maybe another PR, but enter/exit works on Oculus Browser now. |
One sec...fixing last second introduced issue |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
great work one the changes. I've just a few more comments; lmk.
onVRPresentChange: { | ||
value: function (evt) { | ||
// Entering VR. | ||
if (evt.display.isPresenting) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
awesome 👏🏽
enterVRSuccess(); | ||
return Promise.resolve(); | ||
|
||
function enterVRSuccess () { | ||
self.addState('vr-mode'); | ||
self.emit('enter-vr', event); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it might be useful to preserve event
since the event instance will have the reason
, display
, etc. properties.
those values could instead be determined through methods and property lookups on the scene element after enter-vr
is emitted, but it'd help a bit (especially for displaying info, logging/testing, and the WebVR Agent) to know for which display
the scene entered VR.
long story short: can you pass the {display: display}
as the second argument?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think before this was undefined
, but I can rig it to pass something useful.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The event before was just the Enter VR button click event. I won't get to passing in a display in this PR.
@@ -176,24 +183,27 @@ module.exports.AScene = registerElement('a-scene', { | |||
* Call `requestFullscreen` on desktop. | |||
* Handle events, states, fullscreen styles. | |||
* | |||
* @param {bool} fromExternal - Whether exiting VR due to an external event (e.g., |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks; good comment
src/components/scene/vr-mode-ui.js
Outdated
sceneEl.addEventListener('enter-vr', bind(this.updateEnterVRInterface, this)); | ||
sceneEl.addEventListener('exit-vr', bind(this.updateEnterVRInterface, this)); | ||
this.updateEnterVRInterface = bind(this.updateEnterVRInterface, this); | ||
sceneEl.addEventListener('enter-vr', this.updateEnterVRInterface); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know you just added a intermediate variable 👍🏽
asking in case I missed something: there should be code here to remove the (three) event listeners, yeah?
* or immediately (if possible) if display name contains data string. | ||
* The default data string is 'GearVR' for Carmel browser which only does VR. | ||
* Default data string is `GearVR` for Carmel browser which only does VR. | ||
*/ | ||
module.exports.Component = registerComponent('auto-enter-vr', { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm beginning to question the value of this component. I see it served its purpose initially. And it's definitely helpful when in dev environments, especially with Gear VR and iOS (Cardboard). Thoughts, @ngokevin? (This is more intended as a general question, not an issue with this PR. If you agree this ought to be revisited, I'll file a proper bug.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't have an entirely good grasp on the component, seems the useful thing we can keep and move to <a-scene>
module is the display activate handlers. @machenmusik?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See #2707 - now that Oculus Browser is widely available, I think that auto-enter-vr should not be added to scene by default anymore - if developing for Carmel, easy enough to add back in
b947852
to
6166679
Compare
Fixing tests |
@@ -109,16 +109,26 @@ module.exports.AScene = registerElement('a-scene', { | |||
|
|||
// Add to scene index. | |||
scenes.push(this); | |||
|
|||
// Handler to exit VR (e.g., Oculus Browser back button). | |||
this.onVRPresentChangeBound = bind(this.onVRPresentChange, this); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't need to rename and append bound
to the method name.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some leftovers from when I was debugging :P
Description:
Previously, we only handled exitVR on pressing the escape key. Thanks to @DigiTec for pointing in the right direction.
Changes proposed: