1. イントロダクション
バーチャルリアリティ(VR)や拡張現実(AR)アプリケーションを可能にするハードウェアは、現在消費者向けに広く提供されており、没入型のコンピューティングプラットフォームとして新たな機会と課題をもたらしています。没入型ハードウェアと直接やり取りする能力は、この環境においてウェブが一級市民として機能するために不可欠です。WebXR Gamepadsモジュールは、WebXR Device APIおよびGamepads APIにインターフェイスと挙動を追加し、多くのWebXR対応デバイスで入力ソースとして利用できるボタン、トリガー、サムスティック、タッチパッドの状態をクエリできるようにします。
このモジュールはWebXR Device APIへの追加です。
1.1. 用語
このドキュメントではXRという略語を通して、バーチャルリアリティ、拡張現実、その他関連技術で使われるハードウェア、アプリケーション、手法の範囲を指します。例は以下に限定されませんが、含まれます:
-
不透明・透明、またはビデオパススルーを利用するヘッドマウントディスプレイ
-
位置トラッキング機能付きモバイルデバイス
-
ヘッドトラッキング機能付き固定ディスプレイ
それらの重要な共通点は、仮想コンテンツの視点をシミュレートするためのある程度の空間トラッキング機能を持つ点です。
「XRデバイス」や「XRアプリケーション」といった用語は、上記いずれにも一般的に適用されます。本ドキュメントのうちこれらのデバイスのサブセットのみに適用される部分には、適切にその旨が示されます。
XRデバイスには、ボタン、トリガー、サムスティック、タッチパッド入力で没入型体験とやりとりできる追加コントローラーハードウェアが備わっていることがよくあります。これらのデバイスはしばしば空間トラッキングもされ、「モーションコントローラー」や「ハンドヘルドコントローラー」、「トラッキングコントローラー」と呼ばれます。
2. WebXR Device APIとの統合
WebXR Device API API の定義どおり、XRInputSource
はXR入力ソース
を表します。これはユーザーが仮想空間内でターゲットとなるアクションを行うための入力手段です。例としては、ハンドヘルドコントローラー、光学的にトラッキングされる手、視線ベースの入力手法などがあり、ビューアの姿勢に基づいて動作します。
この文書では、XRInputSource
がボタン、トリガー、サムスティック、またはタッチパッドデータを報告する場合の動作について説明します。これは一般的にはモーションコントローラーですが、ヘッドセットにボタンやトリガー、サムスティック、タッチパッドが搭載されている場合もあります。WebXRデバイスAPIで述べられているとおり、XR
デバイスに明示的に紐づかない入力機構(たとえば従来のゲームパッド)はXR入力ソースとみなしてはなりません(MUST NOT)。
2.1. XRInputSource
ボタン、トリガー、サムスティック、タッチパッドのデータは、Gamepad
オブジェクトを通して報告されます。このオブジェクトは、関連付けられたXRInputSourceに公開されます。
partial interface XRInputSource { [SameObject ]readonly attribute Gamepad ?gamepad ; };
gamepad 属性は、Gamepad
であり、XR入力ソース上のあらゆるボタンと軸の状態を記述します。XR入力ソースに次のいずれかのプロパティが少なくとも一つも存在しない場合、gamepad属性はnullでなければなりません(MUST):
-
1つのボタンとgripSpace
-
2つ以上のボタン
-
1つ以上の軸
2.2. XRSession
XRInputSource
は、接続・切断時にinputSources
配列で報告されます。gamepad
の有無がこの配列のいずれかで変化した場合、ユーザーエージェントはWebXR Device APIで定義された入力ソース属性変更への応答アルゴリズムを実行しなければなりません(MUST)。
フレーム更新のリストには、ゲームパッドフレーム更新の適用が含まれるようになります。
ゲームパッドフレーム更新の適用
の手順は、XRFrame
frameについて、ユーザーエージェントが以下の手順を実行することを要求します:
-
XRInputSourceで、当該gamepadgamepadがframe のsessionに関連付けられている場合、次を行う:-
frameのtimeにおけるゲームパッドのデータに合わせてgamepadを更新する。
-
NOTE: これはgamepad
オブジェクトが「ライブ」であり、内部状態が毎フレーム更新されることを意味します。また、XRInputSourceの
gamepadの参照をあるフレームで保存し、後のフレームで同じXRInputSourceの
gamepad
と比較して状態変化をテストすることはできません。なぜならそれは同じオブジェクトだからです。そのため、フレームごとの入力状態を比較したい開発者は当該状態を自らキャッシュすべきです。
3. ゲームパッドAPIとの統合
Gamepad
インスタンスは、XRInputSourceの
gamepad
属性から返されますが、これはGamepad APIで規定されている挙動に加えて、いくつかの追加的な挙動制限があります。
XRInputSource
に関連付けられたGamepad
は、ユーザーエージェントの選択により、XRセッションが活動していない場合でもnavigator.getGamepads()
から取得できる場合があります。これにより、XRデバイスが「通常の」ゲームパッドとして使用可能となります。
Note: [WEBXR-HAND-INPUT-1]で説明されているハンドトラッキングXRInputSource
も、ユーザーエージェントがハンド入力ソースをゲームパッドベースのコンテンツと併用できるようにしたい場合、Gamepadを持つことがあります。
3.1. Navigator
Gamepad APIでは、Gamepad
データのスナップショットはnavigator.getGamepads()
関数で取得可能とされています。しかしながら、XRInputSourceの
gamepad
属性から返されたGamepadインスタンスは、
navigator.getGamepads()
の配列に含まれてはなりません(MUST NOT)。
3.2. Gamepad
以下のGamepad
属性は、XRInputSourceの
gamepad
属性から返される場合、次の制約を満たさなければなりません(MUST):
-
gamepadのindex属性は-1でなければならず(MUST)、ただしnavigator.getGamepads()で公開される場合は未使用ゲームパッドインデックスの選択規定に従うべきです。 -
gamepadのconnected属性は、XRInputSourceがアクティブなXR入力ソースのリストから削除されるか、XRSessionが終了するまでtrueでなければなりません(MUST)。 -
タッチパッドの軸を表すとされる
gamepadのaxes配列の値は、関連付けられたGamepadButtonのtouchedがfalseの時には0でなければなりません(MUST)。
3.3. "xr-standard" ゲームパッドマッピング
"xr-standard"
マッピングはGamepad
APIで定義され、本仕様での使用のために予約されています。これは、gamepad
のボタンや軸のレイアウトが下記表にできる限り準拠することを示します。
マッピングmapping
に"xr-standard"
を報告するためには、デバイスがtargetRayModeとして
"tracked-pointer"
を報告し、さらに非null のgripSpaceを持たなければなりません。それに加えて、タッチパッドやサムスティックとは別の、少なくとも1つの主要トリガーを持たなければなりません。この主要トリガーは入力ソースの主要アクションをトリガしなければなりません(MUST)。また、主要スクイーズボタンを持つ場合、これも主要スクイーズアクションをトリガしなければなりません(MUST)。これらの要件を満たさない場合は、gamepadのmapping属性に空文字列""を報告できます(may)。
| ボタン | xr-standard マッピング
| 必須 |
|---|---|---|
| buttons[0] | 主要トリガー | はい |
| buttons[1] | 主要スクイーズボタン | いいえ |
| buttons[2] | 主要タッチパッド | いいえ |
| buttons[3] | 主要サムスティック | いいえ |
| 軸 | xr-standard マッピング
| 必須 |
|---|---|---|
| axes[0] | 主要タッチパッドX | いいえ |
| axes[1] | 主要タッチパッドY | いいえ |
| axes[2] | 主要サムスティックX | いいえ |
| axes[3] | 主要サムスティックY | いいえ |
上記表でオプションとなっている入力を持たないデバイスは、buttons
またはaxes
配列内のその場所を保持しなければならず(MUST)、プレースホルダーボタンやプレースホルダー軸として報告する必要があります。それぞれのプレースホルダーボタンは、
valueに0、
pressedにfalse、
touchedにfalseを報告しなければなりません(MUST)。プレースホルダー軸
は0を報告しなければなりません。プレースホルダーボタンや軸は、配列の最後の要素か、すべて後続がプレースホルダーであれば省略できます(MUST be omitted)。
これらの予約インデックスの後に追加でボタンや軸を公開することもでき、その場合は重要度の高いものから順に掲載するのが望ましいです。また、関連する軸(例えばサムスティックのX,Y軸)はグループ化し、可能であればX,Y,Z順で並べる必要があります(MUST)。
3.4. UA/プラットフォーム予約ボタン
ユーザーエージェントは、可能であれば、信頼されたUIの一部としてスプーフ不可な操作を行うために、少なくとも1つの物理ボタンを予約すべきです(SHOULD)。たとえば多くのコントローラーに存在する「メニュー」や「アプリ」ボタンは、没入型プレゼンテーションから退出する専用ボタンとして指定できます。さらに多くのXRプラットフォームでは、ホーム環境に戻るなどプラットフォーム固有のアクションのためのボタンも予約しています。
UAまたはプラットフォームにより予約されたボタンは、Gamepadで公開してはなりません(MUST
NOT)。また、ユーザーエージェントはXRプラットフォーム内でどのボタンが予約されているか調整に努めるべきです。WebXR Input
Profiles Registryが予約ボタン調整の推奨場所です。
3.5. マッピング例
"xr-standard"
マッピングでどのように公開されるかを示しています。画像は特定デバイスを示すものではなく、参照用です。4. セキュリティとプライバシー
WebXR Device APIは強力な新機能を提供しますが、それと同時にユーザーエージェントが軽減策を講じるべき複数の独自なプライバシー、セキュリティ、快適性に関するリスクをもたらします。この話題はWebXR Device APIの一部で詳細に取り上げられています。本モジュールは追加的な考慮を加えますが、WebXR のセキュリティとプライバシー 原則を根本的に変更するものではありません。
4.1. フィンガープリンティング
このAPIはユーザーが利用可能なハードウェアとその能力を記述するため、フィンガープリンティングの追加的な対象となります。完全に回避することはできませんが、ユーザーエージェントは軽減に努めるべきです。WebXR
Device APIで定義されているとおり、XRInputSource
はXRSession
が作成された後にはじめて報告され、このときに機微な情報を公開するため追加的な保護が必要です。加えて本モジュールは、XRInputSourceの
gamepad.id
で文字列識別子を報告しないことを要件とします。
変更点
2019年10月10日 第1公開作業草案からの変更点
-
ゲームパッドAPIとの統合は明示的にユーザーエージェントに委ねるよう明記(GitHub #49)
-
予約ボタンは公開しないことを仕様文に追加(GitHub #48)
-
gamepad.indexの定義を緩和(GitHub #46, GitHub #47)
-
主要トリガーおよびリンクボタンの定義を追加(GitHub #24)
-
ゲームパッド状態の更新時の動作を明確化(GitHub #22)
5. 謝辞
WebXR Device API仕様の設計には、以下の方々が貢献されました:
また、Vladimir Vukicevic(Unity)に本プロジェクトの起爆剤となる貢献を特に感謝します!