-
Notifications
You must be signed in to change notification settings - Fork 419
Refactor input identification #695
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
Changes from all commits
1329279
8d87065
57f3ac9
fa238de
4f27cfa
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -228,21 +228,35 @@ For `tracked-pointer` input sources, it is often appropriate for the application | |
| #### Choosing renderable models | ||
| The majority of `tracked-pointer` input sources will have a non-null `gamepad` attribute on the `XRInputSource` object. The `Gamepad`'s `id` is used to determine what should be rendered if the app intends to visualize the input source itself, rather than an alternative virtual object. (See the section on [Button and Axis State](#button-and-axis-state) for more details.) | ||
|
|
||
| The WebXR Device API currently does not offer any way to retrieve renderable resources that represent the input devices from the API itself, and as such the `Gamepad`'s `id` must be used as a key to load an appropriate resources from the application's server or a CDN. The example below presumes that the `getInputSourceRenderableModel` call would do the required lookup and caching. | ||
| The WebXR Device API currently does not offer any way to retrieve renderable resources that represent the input devices from the API itself, and as such the `XRInputSource`'s `profiles` must be used to identify and load an appropriate resources. (For example, from the application's server, a CDN, or a local cache.) The `profiles` provides a list of strings that identify the device, given in descending order of preference. | ||
|
NellWaliczek marked this conversation as resolved.
|
||
|
|
||
| For example, the Samsung Odyssey controller is a variant of the standard Windows Mixed Reality controller. As a result, the `profiles` for that controller could be: | ||
|
|
||
| ```js | ||
| function loadRenderableInputModels(xrInputSource) { | ||
| // Don't load renderable models if the input source doesn't have a gamepad. | ||
| if (!inputSource.gamepad) | ||
| return; | ||
| // Exact strings are examples only. | ||
| ["samsung-odyssey", "windows-mixed-reality", "touchpad-thumbstick-controller"] | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @thetuvix , given that this is your hardware, would you prefer the example strings to be different?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm curious to hear Alex's take on this, but given the time zone differences at the moment I'm going to assume that we can safely handle any concerns that do come up as a follow-up PR.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. "Samsung Odyssey" is a headset and "Windows Mixed Reality" is a platform, so I'd probably go with However, when we populate the initial registry with the identifiers we expect to be used at WebXR 1.0, we can shake out this example to match the registry then. |
||
| ``` | ||
|
|
||
| // Retrieve a mesh to render based on the gamepad object's id and handedness | ||
| let renderableModel = getInputSourceRenderableModel(inputSource.gamepad.id, inputSource.handedness); | ||
| if (!renderableModel) | ||
| return; | ||
| Applications should iterate through the list until a string is located that corresponds to a known model, which should then be used when rendering the input device. The example below presumes that the `getInputSourceRenderableModel` call would do the required lookup and caching. | ||
|
NellWaliczek marked this conversation as resolved.
|
||
|
|
||
| // Add the model to the imaginary 3D engine's scene. | ||
| scene.inputObjects.add(renderableModel, xrInputSource); | ||
| ```js | ||
| function loadRenderableInputModels(xrInputSource) { | ||
| for (let profile of xrInputSource.profiles) { | ||
| // Retrieve a mesh to render based on the gamepad object's profile and handedness | ||
| let renderableModel = getInputSourceRenderableModel(profile, xrInputSource.handedness); | ||
|
|
||
| if (renderableModel) { | ||
| // Add the model to the imaginary 3D engine's scene. | ||
| scene.inputObjects.add(renderableModel, xrInputSource); | ||
| return; | ||
| } | ||
| } | ||
|
|
||
| // If the profiles list was empty or a corresponding model could not be found | ||
| // for any entry in it the application could respond by not rendering the | ||
| // device at all or rendering a generic device that is not intended to be a | ||
| // visual match. This sample chooses the latter approach. | ||
| scene.inputObjects.add(getDefaultInputSourceRenderableModel(), xrInputSource); | ||
| } | ||
| ``` | ||
|
|
||
|
|
@@ -285,19 +299,11 @@ Examples of input sources that may expose their state this way include Oculus To | |
| `Gamepad` instances reported in this way have several notable behavioral changes vs. the ones reported by `navigator.getGamepads()`: | ||
|
|
||
| - `Gamepad` instances connected to an `XRInputSource` must not be included in the array returned by `navigator.getGamepads()`. | ||
| - The `Gamepad`'s `id` attribute must be `""` (empty string). | ||
| - The `Gamepad`'s `index` attribute must be `-1`. | ||
| - The `Gamepad`'s `connected` attribute must be `true` unless the related `XRInputSource` is removed from the `inputSources` array or the related `XRSession` is ended. | ||
|
|
||
| Finally, the `id` attribute for `Gamepad`s surfaced by the WebXR API are more strictly formatted than those of traditional gamepads in order to make them a more appropriate key for determining rendering assets. | ||
|
|
||
| - The `id` MAY be `'unknown'` if the type of input source cannot be reliably identified or the UA determines that the input source type must be masked for any reason. Applications should render a generic input device in this case. | ||
| - Inline sessions MUST only expose `id`s of `'unknown'`. | ||
| - Otherwise the `id` must be a lower-case string that describes the physical input source. | ||
| - The exact format is [still under discussion](https://github.com/immersive-web/webxr/issues/550), but will probably need to include at least an indication of the input device's manufacturer and model. (Such as `oculus-touch`) | ||
| - It must not include an indication of the handedness of the input source (such as `oculus-touch-left`), as that can be determined from the `handedness` attribute. | ||
| - UAs SHOULD make an effort to align on the strings that are returned for any given device. | ||
|
|
||
| All other attributes behave as described in the [Gamepad](https://w3c.github.io/gamepad/) specification. | ||
| The exact button and axes layout is given by the `XRInputSource`'s `profiles` attribute, which contains an array of strings that identify the button and axes layout or subsets of it, ordered from most specific to least specific. | ||
|
|
||
| ```js | ||
| function onXRFrame(timestamp, frame) { | ||
|
|
@@ -413,6 +419,7 @@ interface XRInputSource { | |
| readonly attribute XRSpace targetRaySpace; | ||
| readonly attribute XRSpace? gripSpace; | ||
| readonly attribute Gamepad? gamepad; | ||
| readonly attribute FrozenArray<DOMString> profiles; | ||
| }; | ||
|
|
||
| [SecureContext, Exposed=Window] | ||
|
|
||

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.
Given that we're now enumerating generic profile names in PR #738, how do we feel about requiring the profiles list to have at least one generic profile name in the list?
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 should absolutely strongly recommend it, but I'm not sure if I'm comfortable requiring that for a few reasons:
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.
That makes sense, though I do feel like we could reasonably bend the rules on the first point if we wanted to require a generic profile name for "masked" hardware. Not a blocking issue, though. If this turns out to be a problem we can always add it later.