Unity におけるカスタムカメラ実装 —— 外部フレームデータソース
外部フレームデータソース(ExternalFrameSource)を介して、開発者は EasyAR Sense 向けのカスタムカメラ実装を拡張し、特定のヘッドマウントデバイスやその他の入力デバイスをサポートすることができます。以下の内容では、外部フレームデータソースのタイプ構造とインターフェース定義について説明します。
開始する前に
- カスタムカメラ の基本概念を理解してください。
- フレームデータソース の基本概念、種類、および実行時の選択方法を理解してください。
外部フレームデータソースの種類
---
config:
class:
hideEmptyMembersBox: true
---
classDiagram
class FrameSource {
<<abstract>>
}
class ExternalFrameSource {
<<abstract>>
}
class ExternalDeviceFrameSource {
<<abstract>>
}
class ExternalDeviceMotionFrameSource:::EasyAR {
<<abstract>>
}
class ExternalDeviceRotationFrameSource:::EasyAR {
<<abstract>>
}
class ExternalImageStreamFrameSource:::EasyAR {
<<abstract>>
}
ExternalFrameSource --|> FrameSource
ExternalDeviceFrameSource --|> ExternalFrameSource
ExternalDeviceMotionFrameSource --|> ExternalDeviceFrameSource
ExternalDeviceRotationFrameSource --|> ExternalDeviceFrameSource
ExternalImageStreamFrameSource --|> ExternalFrameSource
classDef EasyAR fill:#6e6ce6,stroke:#333,color:#fff
上図は外部フレームデータソースの種類構造を示しています。
入力データの違いに基づき、外部フレームデータソースは主に2つのカテゴリに分類されます:
- 画像とデバイスモーションデータ入力拡張
- ExternalDeviceMotionFrameSourceの継承によって実装:デバイスおよびデバイスSDKが6DoFモーショントラッキング機能を提供。仮想カメラのtransformおよびその他の制御はデバイスSDKが行います。
- ExternalDeviceRotationFrameSourceの継承によって実装:デバイスおよびデバイスSDKが3DoF回転トラッキング機能を提供。仮想カメラのtransformおよびその他の制御はデバイスSDKが行います。
- 画像入力拡張
- ExternalImageStreamFrameSourceの継承によって実装:画像入力のみを提供。仮想カメラのtransformおよびその他の制御はEasyARが行います。
これらの外部フレームデータソースを接続する際、利用可能なAR機能は以下のように異なります:
- 画像とデバイスモーションデータ入力拡張 ExternalDeviceMotionFrameSource
- Mega
- モーショントラッキング(デバイス自身が提供)
- 疎空間マップ
- 密空間マップ
- 画像トラッキング(モーションフュージョン対応)
- 画像クラウド認識
- オブジェクトトラッキング(モーションフュージョン対応)
- 画像とデバイスモーションデータ入力拡張 ExternalDeviceRotationFrameSource
- Mega
- 画像トラッキング(モーションフュージョン非対応)
- 画像クラウド認識
- オブジェクトトラッキング(モーションフュージョン非対応)
- 画像入力拡張 ExternalImageStreamFrameSource
- 画像トラッキング(モーションフュージョン非対応)
- 画像クラウド認識
- オブジェクトトラッキング(モーションフュージョン非対応)
外部フレームデータソースインターフェース定義
外部フレームデータソースを作成する際には、関連するインターフェースを実装しなければなりません。以下に、これらのインターフェースの定義と使用方法について説明します。
Device definition
FrameSource.IsHMD:
ヘッドマウントディスプレイかどうかを定義
ヘッドマウントディスプレイの場合に限り true に設定されます。
デバイスがヘッドマウントディスプレイの場合、診断情報は画面ではなくカメラ前面の3Dパネルに表示されます。一部のAR機能はヘッドマウントデバイスで動作が若干異なります。FrameSource.Display:
ディスプレイシステムを定義
現在のディスプレイの回転情報などを提供します。
デフォルトのディスプレイ情報は Display.DefaultSystemDisplay または Display.DefaultHMDDisplay で取得できます。 通常、ヘッドマウントディスプレイでは Display.DefaultHMDDisplay が使用可能です。
可用性
- FrameSource.IsAvailable:
可用性(Availability)
フレームソースが使用可能かどうかを判断するために使用されます。
フレームソースが現在の実行デバイスまたは環境で利用できない場合、この値は false であるべきです。
この値が Optional<bool>.Empty に等しい場合、FrameSource.CheckAvailability() コルーチンが呼び出され、コルーチン終了前に FrameSource.IsAvailable を更新する必要があります。
可用性インターフェースはセッションの組み立て時に使用され、利用できないコンポーネントは選択されず、そのメソッドはセッション実行時に呼び出されません。 - FrameSource.CheckAvailability()(オプション):
フレームソースの可用性をチェックするコルーチン
FrameSource.IsAvailable が Optional<bool>.Empty に等しい場合に呼び出されます。このコルーチンが終了するまで、セッションの組み立てプロセスはブロックされます。
session 原点
ExternalDeviceFrameSource.OriginType:
原点タイプ- XROrigin:デバイスSDKはUnity.XR.CoreUtils.XROriginを原点として使用します。
- Custom:デバイスSDKはカスタム原点を使用します。 ExternalDeviceFrameSource.Originの指定が必要です。
- None:デバイスSDKは原点を定義しません。
この場合、原点はシーンから自動的に選択または作成されますが移動しません。
sessionはSessionOriginセンター モードのみをサポートします。アプリ開発者は、すべてのターゲットとターゲット配下のコンテンツがUnity座標系で常に移動するため、仮想オブジェクトの配置に細心の注意を払う必要があります。ユーザーの一部のコンテンツ(物理システムなど)は正常に動作しません。Unityワールド座標系に配置されたオブジェクトは、いかなる設定下でも正しい位置に表示されることは決してありません。
ExternalDeviceFrameSource.Origin:
原点オブジェクト
ExternalDeviceFrameSource.OriginTypeがCustomの場合のみ独自の原点を定義します。それ以外の場合は再定義する必要はありません。
仮想カメラ
- FrameSource.Camera:
仮想カメラ
カメラはセッションによって制御されず、カメラのトランスフォームと投影行列、および画像の背景レンダリングは外部コードで制御する必要があります。
ヘッドマウントディスプレイ上でのみこのカメラが使用され、診断テキストを視界内に表示します。
ExternalDeviceFrameSource.OriginTypeがXROriginの場合、定義は不要です。EasyARはUnity XRフレームワークで定義されたカメラを自動的に使用します。
物理カメラ
- FrameSource.DeviceCameras:
物理カメラパラメータ
カメラフレームデータを提供する物理カメラ。データが複数のカメラから提供される場合、リストには全ての物理カメラを含める必要がある。
FrameSource.CameraFrameStarted が true の際に正しい物理カメラパラメータを取得できることを保証すること。 - FrameSource.CameraFrameStarted:
カメラフレーム入力開始状態
物理カメラが準備されEasyARへデータ入力可能になると true を返し、物理カメラが停止すると false を返す。FrameSource.CameraFrameStarted が false の場合、EasyAR は動作しない。FrameSource.CameraFrameStarted が true の間は、FrameSource.DeviceCameras データへのアクセスが保証され、カメラフレームデータが途切れずEasyARに入力され続ける必要がある。EasyARが長時間カメラフレーム入力の途絶を検出した場合、警告が表示され、機能が応答しない際の問題切り分けを支援する。
物理カメラパラメータは実デバイスカメラと同一である必要がある。
- FrameSourceCamera.CameraType:
物理カメラタイプ
一般にフロントカメラ以外(例:ヘッドマウントディスプレイ)ではリアカメラを選択する。 - FrameSourceCamera.CameraOrientation:
物理カメラ画像をデバイスの自然な向きで表示する際に必要な時計回り回転角度
範囲は [0, 360)。 - FrameSourceCamera.FrameSize:
画像サイズ - FrameSourceCamera.FrameRateRange:
フレームレート範囲
x をフレームレート範囲の下限、y を上限として定義する。 - DeviceFrameSourceCamera.AxisSystem:
ヘッド/物理カメラの姿勢(pose)および物理カメラ外部パラメータが使用する座標軸システム
全ての行列は同一の座標軸システムを使用する必要がある。データ定義が既知のシステムに合致しない場合、EasyARへ渡す前に座標軸変換を行う必要がある。 - DeviceFrameSourceCamera.Extrinsics:
物理カメラ外部パラメータ
一般に較正された行列。その座標軸は DeviceFrameSourceCamera.AxisSystem の定義に従う必要がある。外部パラメータの座標軸定義が実際の姿勢(pose)の定義と異なる場合、またはそれらが DeviceFrameSourceCamera.AxisSystem の定義に合致しない場合、この値を設定する前に座標軸変換を行う必要がある。
Session start and stop
- FrameSource.OnSessionStart(ARSession):
セッション開始イベントの処理
このフレームソースがセッションのアセンブル時に選択された場合に有効です。
AR固有の初期化作業をこのメソッド内で行う遅延初期化に利用できます。 - FrameSource.OnSessionStop():
セッション停止イベントの処理
このフレームソースがセッションのアセンブル時に選択された場合に有効です。
FrameSource.OnSessionStart(ARSession) およびセッション実行中に作成されたリソースを破棄し、内部状態を復元するためにこのメソッドを使用できます。セッション破棄前にこのメソッドが呼び出されることが保証されます。フレームソースがセッションより先に破棄された場合、このメソッドは呼び出されず、セッションは Broken 状態に遷移します。
入力フレーム
ExternalDeviceRotationFrameSource.HandleCameraFrameData(DeviceFrameSourceCamera, double, Image, CameraParameters, Quaternion):
カメラフレームデータを入力
デバイスSDKのAPIがスレッドセーフであれば、任意のスレッドで呼び出し可能。
物理カメラセンサーの露光時と一致するデータを入力する必要がある。30fpsまたは60fpsのデータ入力を推奨。最小許容フレームレートは2だが、一部アルゴリズムの応答時間に影響する。取得可能な場合はカラーデータを入力することを推奨(Megaの効果向上に有効)。
最適な効率化のため、生YUVデータを共有メモリ経由で直接渡し、データポインタをEasyARに直接入力するデータチェーン設計が可能。データ所有権に注意。ExternalDeviceMotionFrameSource.HandleRenderFrameData(double, Pose, MotionTrackingStatus):
レンダリングフレームデータを入力ExternalDeviceRotationFrameSource.HandleRenderFrameData(double, Quaternion):
レンダリングフレームデータを入力
デバイスデータ準備後にレンダリングフレームごとに呼び出す必要があり(フレームスキップ不可)。同一フレーム内のUnity仮想カメラを駆動するデータと一致させること。
- ExternalFrameSource.TryAcquireBuffer(int):
メモリプールからメモリブロックを取得試行
このメモリブロックは通常、カメラフレームの画像データを保存してEasyARに入力するために使用される。 - ExternalFrameSource.ReceivedFrameCount:
EasyARが取得したカメラフレームカウント
EasyARはこれを使用してデバイスカメラフレーム入力の健全性を確認する。デバッグ時に使用可能。この値の増加が停止した場合、通常はデバイスがEasyARへのデータ入力を停止したことを示す。
Unity メッセージ
スクリプトで以下のメッセージを使用する際は、基底クラスの実装が呼び出されるように注意してください:
次のステップ
- 外部入力フレームデータ を読み、カメラフレームデータとレンダリングフレームデータを理解する
- 画像とデバイスモーションデータ入力拡張 を作成する
- 画像入力拡張 を作成する
関連トピック
### 翻訳のポイント
1. **タイトル形式**: "関連トピック" を文頭のみ大文字の「Sentence case」に統一
2. **英語保持**: "AR Session", "Camera", "XR Origin" は原文のまま
3. **リンクテキスト**:
- [センター モード] (元の中国語「中心模式」を日本語訳)
- [EasyARのヘッドマウント サポート] (ハイフン周辺のスペース削除)
4. **パス保持**: すべての相対パス(`../fundamentals/~`, `~/develop/~`)は変更なし
5. **記号保持**: Markdown記号(`##`, `-`, `[]()`, `~`)は完全に維持
6. **ハイフン処理**: 「ヘッドマウント」(head-mounted) のハイフン前後にスペースなし