入力データの概要 更新日時: 2024/08/07
このトピックでは、Interaction SDKがトラッキングデータをどのように取得、構造化、修正して、インタラクションを作成するかを説明します。Interaction SDKのすべてのインタラクションは、SDKがヘッドセットのカメラとコントローラーから直接受け取る、ヘッドセットの手とコントローラーの位置と回転に関する正確なデータに依存しています。
Interaction SDKは、一連のインターフェイス(
IController、
IHand、
IHmd、
IBody)を使って入力データをフォーマットします。インターフェイスはそれぞれ、特定のタイプのデータを処理します。例えば、
IHandは生のハンドデータを解釈し、
IControllerは生のコントローラーデータを解釈します。インターフェイスによって、生の入力データが、Interaction SDKコンポーネントやprefabが理解できるような仕方で編さんされます。
OVR (Oculus仮想現実)プラグイン(ヘッドセット)から生の入力データを実際に取得する場合、Interaction SDKは、[From OVR...Source (OVR ...ソースから)] または[From Unity XR ...Source (Unity XR ...ソースから)] のコンポーネントを使います。「...」部分にはデータのソースが入ります(例: From OVR Body Data SourceまたはFrom OVR Hand Data Sourceなど)。[From ...Source (... ソースから)] のコンポーネントはそれぞれ特定のタイプのデータを取得し、3つのインターフェイスのうちのいずれか1つを使ってそれを整理します。インタラクションは、これらのコンポーネントから得たデータを利用して、手、コントローラー、または体の位置を決定します。これらのコンポーネントは、関連するInteraction SDK prefabにすでに含まれているため、手動で追加する必要はありません(例えば、OVRHands prefabには[From OVR Hand Data Source (OVRハンドデータソースから)] コンポーネントが、またUnityXRHands prefabには[From Unity XR Hand Data Source (Unity XRハンドデータソースから)] コンポーネントが含まれています)。
From ...Source コンポーネントには、次のものがあります。
Meta Interaction SDKパッケージ
From OVR Body Data Source (OVRボディデータソースから) From OVR Controller Data Source (OVRコントローラーデータソースから) From OVR Controller Hand Data Source (OVRコントローラーハンドデータソースから) From OVR Hand Data Source (OVRハンドデータソースから) From OVR Hmd Data Source (OVR HMDデータソースから) Unity XR Handsがインストールされている場合のMeta Interaction SDK Essentialsパッケージ
From Unity XR Hand Data Source (Unity XRハンドデータソースから) From Unity XR Controller Data Source (Unity XRコントローラーデータソースから) From Unity XR Hmd Data Source (Unity XR HMDデータソースから) ヘッドセットから各[From ...Source (... ソースから)] コンポーネントに送られる生の入力データ。それぞれが、3つのInteraction SDKインターフェイスのうち1つを使う。
[From ...Source (... ソースから)] コンポーネントから入力データを取得したら、
Interactor がそれを使えるようになります。ただし、ハンドデータはInteractorに
ルーティング (送信)される前に処理可能です。その他のタイプの入力データの処理は不要です。ハンドデータを処理することにより、次のことができます。
ジッター(ゆらぎ)の最小化や除去 ボタンを押すときや仮想オブジェクトをつかむときなど、仮想の手の指を物理的な指とは違うポーズにする。 レイインタラクターの起点を、物理的な手やコントローラーではなく、仮想の手やコントローラーの位置に基づいてオフセットする。 ハンドデータを処理するには、そのデータを
IHand インターフェイスを使う特定のコンポーネント(
HandFilter など)に渡した後、そのコンポーネントを
[From ...Source (... ソースから)] コンポーネントの代わりにInteractorのデータソースとして使います。この操作は、手を使っている場合にもコントローラー駆動の手を使っている場合にも実行します。
HandGrabExamples シーンから取得したハンドデータを処理するおすすめの方法を以下に示します。この処理をpokeやgrab以外のインタラクションに使う場合は、
SyntheticHand を省略します。手が視覚的に正しく見えるようにするために手の関節データを修正することが必要なのは、pokeとgrabの場合だけだからです。
ハンドデータがレンダリングされる前に複数のコンポーネントで処理されているところ。
これらのコンポーネントによってハンドデータがどのように処理されるかを以下に示します。
FromOVRHandDataSource はOVRHand から得たデータをIHand を使って変換し、そのデータをInteraction SDKのコンポーネントが認識できるようにします。
FromUnityXRHandDataSource コンポーネントを使う場合は、Unity XRの手から受け取ったOpenXRデータがCore SDKハンドデータに変換されます。HandFilter は、指定されたフィルターを使って入力の手の位置データを滑らかにして、ジッターを減らします。
SyntheticHand は、関節データをオーバーライドすることにより手のポーズを調整します。これは、pokeの際に指がボタンを突き抜けてしまわないようにしたり、物をつかむ際の指がポーズに沿ったものになるようにしたりするためです。
HandVisual は、処理済みのデータを使って手をレンダリングします。
動画 : レンダリングされた手がボタンやタッチパッドオブジェクトに触れる様子。
SyntheticHand で処理されていないハンドデータとSyntheticHand で処理されたデータの違い。pokeの際、未処理データを使う手はボタンを突き抜けるが、処理済みデータを使う左手の場合は視覚的にpokeが制限される。
手とコントローラーの入力データは、最終的にInteractorに送られます。上記のセクションに示されているコンポーネントも含め、すべてのハンドデータコンポーネントにはIHand が実装されているため、そのいずれかを使うことによってアプリのさまざまな側面を駆動します。例えば、レイインタラクションでは、HandFilter のハンドデータを使ってレイ(光線)の起点を設定したり、SyntheticHand を使って手のビジュアルを設定したりすることができます。
アプリのさまざまな部分にデータをルーティングする。上の図の場合、RayInteractor はハンドデータを受け取って物理的手の位置を判定するが、HandVisual はそのデータのフィルターバージョンを受け取って仮想の手の動きをスムーズにする。下の図のSyntheticHand は、2組のデータを受け取る。Hand から直接受け取るデータは物理的な手の位置を示すものであり、HandGrabVisual から得るデータは何かをつかむ際の仮想手の外観を決定する。
OVRInteraction prefabは、手、コントローラー、コントローラー駆動の手のための取り付けの基盤となるものです。
デフォルトの場合、OVRInteraction prefabのコンテンツは以下のみになります。
Interaction SDKに含まれる、手のための基本データコンポーネントは、Hand と呼ばれます。
Hand は、手に関連したポーズデータ、ピンチの状態、ポインターポーズ、入力可能性を提供します。
このデータは、FromOVRHandDataSource コンポーネントによって、OVRHand から得られます。FromUnityXRHandDataSource コンポーネントにより、Unity XRの手から受け取ったOpenXRデータがCore SDKハンドデータに変換されます。
IHand は、Handデータへのアクセスに使う基本インターフェイスです。コンポーネントでは、実際のHand ではなく、IHand インターフェイスを使って手のデータを利用するようにしてください。
HandRef は、IHand コンポーネント用のパススルーコンポーネントです。すべてのInteractor prefabのルートGameObjectには、その子コンポーネントを紐付けることのできるHandRef コンポーネントがあります。
こうする主なメリットは、インタラクションprefabの接続に必要なシーンの紐付けを最小限に減らせることです。Hand をOVRInput prefabからインタラクションprefab内の各コンポーネントに紐付けなくても、prefabの最上位のHandRef に紐付けるだけで、prefab中のすべての子オブジェクトはそのHandRef を参照するようになります。
Interaction SDKの中で、コントローラー用の基本データコンポーネントは、Controller と呼ばれます。
Controller は、コントローラーのポーズデータ、ボタンの状態、コントローラーに関連した入力可能性を提供します。
このデータは、
FromOVRControllerDataSource コンポーネントによって、
OVRInput から得られます。
FromUnityXRControllerDataSource コンポーネントは、このデータを
Unity入力システム のOpenXRサポートから取得します。
IController は、Controllerデータへのアクセスに使う基本インターフェイスです。コンポーネントでは、実際のController ではなく、IController インターフェイスを使ってコントローラーのデータを利用するようにしてください。
ControllerRef は、HandRef と同じく、IController コンポーネント用のパススルーコンポーネントです。コントローラーを参照するすべてのInteractor prefabのルートGameObjectには、子コンポーネントを紐付けできるControllerRef コンポーネントがなければなりません。
データは、OVRPluginから、いくつかのクラスを経由してController やHand などのデータ型へと送られます。それらのどれについても、総称基底クラスであるDataSource<TDataType> を通じてIDataSource が実装されています。
このインターフェイスの最も重要なフィールドはIDataSource.InputDataAvailable イベントです。これを介して、更新されたトラッキングデータやポーズデータが、さまざまなコンポーネントから依存対象に渡されます。
派生クラスDataSource は、特定の型(HandDataAssetなど)のデータを提供できます。
DataModifier (それ自体DataSourceから派生)によって、さらに機能が追加されます。これはHandDataAsset上で後処理機能の働きをします。DataModifierは、DataSourceからデータを読み、変更を適用し、結果をキャッシュに入れた後、IDataSourceインターフェイスを通じてそれらの結果を提供します。
LastKnownGoodHand は、手に関する既知の最後の良好なデータを、下位の修正チェーンに渡すことのみ行います。それに提供されるデータが何らかの理由(トラッキングが失われた、トラッキング品質が低いなど)で無効になった場合、有効な最後の手データが維持されます。
SyntheticHand は、手の関節データ(指や手首の位置や回転を含む)に対して手動で変更を加えるために使うことができます。HandGrab シーンでは、これを使ってマグカップのつかみ方が調整されています。ボタンを押した際に指をどこまで動かせるかを視覚的に制限する場合にも使われます。これはpoke制限と呼ばれます。
フレームのインタラクションロジックがすべて完了したら(通常はフレームの最後)、SyntheticHand を更新してください。
SyntheticHand は、希望するポーズに収めることによって、または回転量と拡散の上限を設定することによって、関節を円滑にロック/ロック解除します。指定された曲線と速度を調整すれば、スナップの加減を調整できます。
SyntheticHand への直接呼び出しによって、関節をオーバーライドすることができます。それ以外のコンテキストでは、ジョイントのロックとロック解除を処理するためのコンポーネントがあります。
手による突きタッチ制限 では、HandPokeLimiterVisual によりこのモディファイアが駆動します。手づかみポーズ では、HandGrabInteractorVisual によりこのモディファイアが駆動されます。複数のInteractorVisualが同時にジョイントをロックまたはロック解除しようとする可能性があるため、
InteractorGroup により、
SyntheticHand に作用するInteractorVisualが常に1つだけになるようにすることができます。
HandFilter では、1ユーロフィルターを使用して、入力ストリームの位置データと回転データの両方を補正します。1ユーロフィルターは、遅延を増大させることなく値を安定させるのに役立つ、速度ベースのフィルターです。任意で[Filter Parameters(フィルターパラメーター)] フィールドが、HandFilterParameterBlock アセットを使って設定されます。このアセットには、手首の位置、手首の回転、指の回転に関する以下の値が含まれています。
ベータ(0は遅延最大、10は遅延最小)。 最小カットオフ(0の場合はフィルター補正最大かつ遅延増大、10の場合はフィルター補正最小)。 Dカットオフは、微分カットオフを表し、エフェクトをさらに細かく調整するために使用できます。 さらに、HandFilterParameterBlock は、1秒当たりのフレーム数として測定した頻度値が含まれています。これが1ユーロフィルターに渡されます。[Filter Parameters(フィルターパラメーター)] に値が設定されていない場合、フィルターは適用されません。
Interaction SDKに含まれるボディ用の基本データコンポーネントは、Body と呼ばれます。
使っているのがUnity XRデータソースだけの場合、ボディデータは利用できません。
IBody は、Bodyデータへのアクセスに使う基本インターフェイスです。コンポーネントでは、実際のBody ではなく、IBody インターフェイスを使ってボディのデータを利用するようにしてください。
体の骨組みにはそれぞれ異なる関節セットや親子関係が含まれることがあり、これらのパラメーターはISkeletonMapping によって表されます。
関節にローカルポーズデータを使う場合、その関節の親が認識されていなければ、データを有効活用できません。特定の関節の親を見つけるには、ISkeletonMapping.TryGetParentJointId() メソッドを使います。
BodyJointId には膨大な関節が含まれており、現在の骨組みデータでは利用できないことがあります。使用するには、事前にISkeletonMapping.Joints HashSetで特定の関節が存在しているかどうかチェックする必要があります。
BodySkeletonMapping はScriptableObjectであり、ISkeletonMapping を含んでいます。これ自体には、ISkeletonMapping インターフェイスが公開されています。
Interaction SDKアーキテクチャー全概要については、アーキテクチャーの概要 をご覧ください。 インタラクションを開始するために手やコントローラーに接続されているInteractorについて詳しくは、Interactor をご覧ください。 Interactorに応答するオブジェクトに接続されているInteractableについて詳しくは、Interactable をご覧ください。 同時に複数のホバリングがある場合にどのようにInteractorを優先順位付けするかについて詳しくは、InteractorGroup をご覧ください ボディポーズ検出のコンポーネントについて詳しくは、ボディポーズ検出 をご覧ください。