Closed takahirox closed 4 years ago
IIUC, the issue is input sources are not available until at least one animation frame elapses.
Not sure if this was intentional or not (ping @toji), but IIUC the spec correctly, it makes sense that the inputSources
are not populated before those steps can be run (e.g. fire an event with a new array). It appears waiting a frame would work just as well, spec-wise.
That being said, I'd expect for three.js to respond to that event, and not rely on it being available at session creation (if in fact the polyfill is firing that event for the input sources after the first animation frame).
IIUC, the issue is input sources are not available until at least one animation frame elapses.
Yes, correct. Code snippet
navigator.xr.requestSession('immersive-vr', sessionInit).then(session => {
session.updateRenderState({baseLayer: new XRWebGLLayer(session, gl)});
session.requestReferenceSpace(referenceSpaceType).then(onRequestReferenceSpace);
// session.inputSources is an empty array here with the polyfill
// even if some controllers(gamepads) are available.
inputSources = session.inputSources;
....
});
And thanks for the comment. Just in case, I want to also hear the comment fom @toji and if it's a correct behavior I'll try to fix the problem in Three.js side.
https://immersive-web.github.io/webxr/#xrsession-interface
When new XR input sources become available for XRSession session, the user agent MUST run the following steps:
- Let added be a new list.
- For each new XR input source:
- Let inputSource be a new XRInputSource.
- Add inputSource to added.
- Queue a task to perform the following steps:
- Extend session’s list of active XR input sources with added.
- Fire an XRInputSourcesChangeEvent named inputsourceschange on session with added set to added.
If I understand correctly, inputsourceschange
event should be fired when inputSources
are populated at the first animation frame, correct?
If the polyfill will do so, Three.js doesn't need to be fixed because it watches inputsourceschange
event and update its inputSources
when it's fired.
https://github.com/mrdoob/three.js/blob/r108/src/renderers/webvr/WebXRManager.js#L146-L158
Related: #37
inputsourceschange
event is implemented in the polyfill and the problem I faced should be solved. Closing this issue.
Background
If
XRSession.inputSources
is accessed it callsdevice.getInputSources()
wheredevice
isWebVRDevice
.https://github.com/immersive-web/webxr-polyfill/blob/master/src/api/XRSession.js#L314
WebVRDevice.getInputSources()
returns an array composed from its.gamepadInputSources
https://github.com/immersive-web/webxr-polyfill/blob/master/src/devices/WebVRDevice.js#L567
.gamepadInputSources
is empty first, and they're set up inonFrameStart()
.https://github.com/immersive-web/webxr-polyfill/blob/master/src/devices/WebVRDevice.js#L295
I faced a problem in Three.js with this behavior. Three.js keeps
session.inputSources
and uses later here.https://github.com/mrdoob/three.js/blob/r108/src/renderers/webvr/WebXRManager.js#L144
But the above line is called before the first immersive animation frame is invoked. So
inputSources
is an empty array even if some controllers exist.Question
Is this behavior intentional? If so, should the problem be fixed in Three.js side?
The spec mentions
https://immersive-web.github.io/webxr/#xrsession-interface
I'm not really sure exactly when they should be set up. (Sorry if I'm missing) In immersive animation frame? Or synchronously when
XRSession
is instanciated if controllers are already available?