空間コンテナは、OpenXR にボリュメトリック ウィンドウ処理をもたらします。OpenXR 1.1 の XR_EXT_spatial_container 拡張機能と XR_EXT_spatial_container_self_rendering 拡張機能で定義されている空間コンテナは、ユーザーの空間内のシステム管理の 3D ボリューム領域です。アプリは、標準の OpenXR コンポジション レイヤを使用して 3D コンテンツをレンダリングします。
従来、OpenXR セッションはユーザーの画角全体への排他的アクセスを要求します。空間コンテナを使用すると、アプリはユーザーの環境内の境界付き 3D ボックス内に 3D OpenXR コンテンツをレンダリングしたり、いつでも境界のない全画面表示の没入型エクスペリエンスに移行したりできます。
空間コンテナについて
空間コンテナは、Android XR システムによって管理され、OpenXR アプリによってレンダリングされる、境界付きまたは境界なしの 3D 領域です。
- 境界モード: アプリが 3D 寸法(幅、高さ、奥行き(メートル単位))を提案し、システムがユーザーの環境に 3D 境界ボックスを割り当てます。アプリはボリューム内にステレオ 3D コンテンツをレンダリングし、システムはレンダリングされたコンテンツを 3D ボックスの境界にクリップします。
- 没入モード: 空間コンテナが無限の境界に拡張され、従来のフルスクリーン OpenXR セッションのように、ユーザーの画角全体がアプリに提供されます。
ユーザーが空間コンテナを操作する方法
Android XR システムは、空間コンテナのウィンドウ コントロールと物理空間での配置を管理し、アプリ間で一貫したインタラクション モデルを提供します。
- 移動と再配置: ユーザーは、ハンド ジェスチャー(ピンチなど)やモーション コントローラを使用して、空間コンテナのシステム ハンドルを掴み、3D 空間で再配置できます。
- 最小化と終了: システム ウィンドウ コントロールを使用すると、ユーザーは個々の空間コンテナを最小化または終了できます。ユーザーがコンテナを閉じると、システムはアプリに通知し、アプリがリソースをクリーンアップできるようにします。
- シーン認識による床へのロック: アプリが
android.permission.SCENE_UNDERSTANDING_COARSE権限を宣言してリクエストすると、システムは自動的にサーフェス スナップを有効にします。これにより、ユーザーは追加のアプリ構成なしで、空間コンテナを物理的な床に配置してロックできます。図 1 のオレンジ色の地形コンテナがその例です。 - 直接 3D 操作: コンテナがフォーカスされ、操作可能な場合、ユーザーはハンド トラッキング、視線、6DoF コントローラを使用して、ボリューム内の 3D コンテンツを直接操作できます。
- 境界モードと没入モードの切り替え: ユーザーまたはアプリは、OpenXR セッションを再起動することなく、境界付き 3D ボックスと境界なしの全画面没入ビューの間でコンテナを切り替えることができます。
- 移動中のフォローモード: システムが各空間コンテナの座標空間(
xrCreateSpatialContainerSpaceEXT)のポーズを制御するため、ユーザーはシステム ウィンドウ コントロールからフォローモードを有効にできます。これにより、境界付き 3D コンテナが自動的にユーザーを追跡し、ユーザーが歩き回っている間も画角内に留まります。アプリで追加の構成は必要ありません。
Android XR で空間コンテナを使用する方法
Spatial Containers を使用してアプリを構築する場合は、コンテナの境界、状態の変化、背景ブレンドモードを中心にシーンを設計します。
3D コンテンツをコンテナの境界に合わせる
境界モードでは、空間コンテナ空間(xrCreateSpatialContainerSpaceEXT)の原点 (0, 0, 0) は 3D 境界ボックスの中心にあります。システムはユーザーの環境におけるコンテナ空間のポーズを管理するため、アプリは (0, 0, 0) を基準に 3D コンテンツをレンダリングし、システムはユーザーの再配置とフォローモードを処理します。システムは、ボックスの幅、高さ、奥行きの外側にレンダリングされたジオメトリをクリップして、コンテンツが割り当てられたボリューム内に収まるようにします。
アプリは、ランタイムからの境界変更イベントをリッスンし、3D シーンをスケーリングまたは再配置して、主要なコンテンツがコンテナの現在のサイズに収まるようにする必要があります。コンテナが没入モードに移行すると、境界は無限になり、シーンを完全な 1:1 のワールド スケールに復元できます。
コンテナの状態の変化に対応する
各空間コンテナは、アプリケーション レベルでのみ可視性とフォーカスを管理するのではなく、独自の状態を報告するため、アプリはそれに応じて対応できます。
- 公開設定: コンテナが現在表示されているか非表示になっているかを示します。コンテナが非表示になっている間は、アニメーション、音声、シミュレーションの更新を一時停止します。アプリは、コンテナの表示または非表示をリクエストすることもできます。
- インタラクション可能性: コンテナがフォーカスされ、ハンド トラッキング、コントローラ、視線からユーザー入力を受け取っているかどうかを示します。フォーカスが変更されたときに、インタラクティブなハイライト表示と入力処理を有効または無効にします。
- 境界モード: コンテナが現在
XR_SPATIAL_CONTAINER_BOUNDS_MODE_BOUNDED_EXT(3D ボックスにクリップされている)かXR_SPATIAL_CONTAINER_BOUNDS_MODE_IMMERSIVE_EXT(境界のない全画面表示)かを示します。モードが変更されたときに、シーンのスケールを更新し、環境ビジュアル(スカイボックスやパススルーなど)を切り替えます。アプリは、境界モードと没入モードの間の切り替えをいつでもリクエストできます。
境界モードでアルファ ブレンドの透明度を使用する
境界モードでは、背景が透明になるため、3D モデルの周囲にユーザーの物理的な環境や他のウィンドウが表示されます。透明な背景でカメラまたはビューポートを構成し、アルファブレンド環境ブレンドモードを使用します。没入モードに切り替えるときに、パススルーを有効にしたままにするか、不透明なスカイボックス環境に切り替えることができます。
機能の可用性を確認してマニフェストを構成する
空間コンテナには、空間 API レベル 4 以降をサポートする Android XR デバイスが必要です。Android API レベルを直接確認するのではなく、OpenXR ランタイムにクエリして、空間コンテナがサポートされているかどうかを判断します。xrEnumerateInstanceExtensionProperties を呼び出して XR_EXT_spatial_container と XR_EXT_spatial_container_self_rendering が使用可能であることを確認し、XrSystemSpatialContainerPropertiesEXT を指定して xrGetSystemProperties を呼び出して supportsBounded と supportsImmersive を検査します。
Spatial Containers を使用するアプリをビルドする前に、AndroidManifest.xml でアクティビティの開始モードと機能固有の権限を構成します。
AndroidManifest.xml でフルスペース モードを有効にする
空間コンテナには、スタンドアロンの OpenXR アプリであっても、フルスペース マネージド モードが必要です。従来の全画面 OpenXR アプリは、システム ウィンドウ管理なしでディスプレイを排他的に制御するために XR_ACTIVITY_START_MODE_FULL_SPACE_UNMANAGED を宣言します。一方、空間コンテナを使用するアプリは、Android XR システム コンポジタに依存して、フルスペース モードで 3D 境界ボリューム、ウィンドウ コントロール、空間配置を管理します。また、android.window.PROPERTY_XR_ACTIVITY_START_MODE を XR_ACTIVITY_START_MODE_FULL_SPACE_MANAGED に設定する必要があります。
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application ...>
<!-- Spatial Containers require Full Space Managed mode -->
<property
android:name="android.window.PROPERTY_XR_ACTIVITY_START_MODE"
android:value="XR_ACTIVITY_START_MODE_FULL_SPACE_MANAGED" />
<activity android:name=".MainActivity" ...>
<!-- Optional hint declaring which bounds modes the activity uses -->
<property
android:name="org.khronos.openxr.PROPERTY_ACTIVITY_HINT_XR_SPATIAL_CONTAINER_USED_BOUNDS_MODES"
android:value="XR_SPATIAL_CONTAINER_BOUNDS_MODE_BOUNDED_EXT|XR_SPATIAL_CONTAINER_BOUNDS_MODE_IMMERSIVE_EXT" />
</activity>
</application>
</manifest>
機能固有の権限を宣言してリクエストする
基本的な空間コンテナの作成とレンダリングには、危険な実行時の権限は必要ありません。ただし、特定の機能では、対応する Android XR 権限を宣言してリクエストする必要があります。
- シーン認識を使用して空間コンテナを物理的な床にロックして固定するには、実行時に危険な
android.permission.SCENE_UNDERSTANDING_COARSE権限を宣言してリクエストします。 - OpenXR でユーザーの頭部のポーズを追跡するには、
android.permission.HEAD_TRACKINGを宣言してリクエストします。
<uses-permission android:name="android.permission.HEAD_TRACKING" />
<uses-permission android:name="android.permission.SCENE_UNDERSTANDING_COARSE" />
実行時に危険な XR 権限を宣言してリクエストする方法については、XR の権限についてをご覧ください。
プロジェクトで Spatial Containers を有効にする
Spatial Containers を使用してビルドするには、Unity、Godot、または C++ で OpenXR を直接使用します。タブを選択して、お好みの環境の前提条件、エディタの設定、コード例を確認してください。
Unity
前提条件
- Unity のバージョン: Unity 6 バージョン 6000.0.58f2 以降。
- プロジェクトの設定: Unity プロジェクトの設定ガイドのすべての手順を完了します。
- Unity パッケージ: Android XR Extensions for Unity パッケージのバージョン 1.5.0 以降をインストールします。
プロジェクトを構成する
- [Edit] > [プロジェクト設定] > [XR Plug-in Management] > [OpenXR] に移動します。
- [Android XR (Extensions): Session Management] の横にある設定アイコン をクリックし、[Immersive XR] をオフにします。
- [OpenXR Feature Groups] リストで、[Spatial Container] を有効にします。
C# で XRSpatialContainerFeature を使用して、境界のクエリ、コンテナ イベントへの応答、境界モードと没入モードの切り替えを行います。
void OnEnable()
{
XRSpatialContainerFeature.OnSpatialContainerBoundsChanged += OnBoundsChanged;
}
private void OnBoundsChanged(Vector3 bounds, bool infiniteBounds)
{
float minScale = Mathf.Min(bounds.x, bounds.y, bounds.z);
transform.localScale = infiniteBounds ? Vector3.one : Vector3.one * minScale;
}
public void SetImmersiveMode(bool immersive)
{
XRSpatialContainerFeature.TryRequestBoundsMode(immersive);
}
プロジェクトの設定手順、マニフェストの構成、権限の処理の詳細については、Unity で空間コンテナを使用するをご覧ください。
Godot
前提条件
- Godot のバージョン: Godot 4.8-dev 以降。
- プロジェクトの設定: Godot Engine プロジェクトの設定ガイドのすべての手順を完了します。
- Godot OpenXR ベンダー プラグイン: バージョン 5.2 以降の Godot OpenXR ベンダー プラグインをインストールします。
プロジェクトを構成する
- プロジェクト設定 に移動し、Advanced Settings を有効にして、[General] > [XR] > [OpenXR] > [Extensions] に移動します。
- [Spatial Container] サブセクションで [Enabled] を選択し、[Bounds Mode] と [Bounds] を構成します。
- [Project] > [Export...]> [Android] を選択し、[Android XR Features] で [Use Experimental Features] を選択します。
GDScript の OpenXRSpatialContainerExtension シングルトンを使用して、コンテナの境界とモードの変更に対応します。
func _ready() -> void:
if OpenXRSpatialContainerExtension.is_enabled():
OpenXRSpatialContainerExtension.spatial_container_bounds_changed.connect(
_on_bounds_changed
)
func _on_bounds_changed(_rid: RID, bounds: Vector3) -> void:
scale = Vector3.ONE * min(bounds.x, bounds.y, bounds.z)
func set_immersive_mode() -> void:
OpenXRSpatialContainerExtension.request_main_spatial_container_bounds_mode(
OpenXRSpatialContainerState.IMMERSIVE
)
プロジェクト設定、エクスポート権限、GDScript の例の詳細については、Godot で Spatial Container を使用するをご覧ください。
OpenXR
前提条件
- OpenXR バージョン:
XR_EXT_spatial_containerとXR_EXT_spatial_container_self_renderingを含む OpenXR 1.1 ヘッダー。 - マニフェストの設定:
XR_ACTIVITY_START_MODE_FULL_SPACE_MANAGEDを使用して、Android XR 向け OpenXR のスタートガイドの説明に沿ってアプリ マニフェストを構成します。
XrInstance の作成時に XR_EXT_spatial_container と XR_EXT_spatial_container_self_rendering を有効にしてから、空間コンテナを作成してレンダリングします。
// 1. Enable the Spatial Container extensions during xrCreateInstance
const char* enabledExtensions[] = {
XR_EXT_SPATIAL_CONTAINER_EXTENSION_NAME,
XR_EXT_SPATIAL_CONTAINER_SELF_RENDERING_EXTENSION_NAME,
};
// 2. Configure and create a self-rendering spatial container
XrSpatialContainerConfigurationSelfRenderingEXT selfRenderingConfig{
.type = XR_TYPE_SPATIAL_CONTAINER_CONFIGURATION_SELF_RENDERING_EXT,
.next = nullptr,
.viewConfigurationType = XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO,
.suggestedBounds = {1.5f, 1.5f, 1.5f}, // Width, height, depth in meters
};
XrSpatialContainerCreateInfoEXT createInfo{
.type = XR_TYPE_SPATIAL_CONTAINER_CREATE_INFO_EXT,
.next = &selfRenderingConfig,
.spatialContainerConfig =
reinterpret_cast<const XrSpatialContainerConfigurationBaseHeaderEXT*>(
&selfRenderingConfig),
};
XrSpatialContainerEXT spatialContainer = XR_NULL_HANDLE;
xrCreateSpatialContainerEXT(session, &createInfo, &spatialContainer);
// 3. Request bounded mode and make the container visible
xrRequestSpatialContainerBoundsModeEXT(
spatialContainer, XR_SPATIAL_CONTAINER_BOUNDS_MODE_BOUNDED_EXT);
xrRequestSpatialContainerVisibilityEXT(spatialContainer, XR_TRUE);
関連情報
OpenXR™ および OpenXR ロゴは、The Khronos Group Inc. が所有する商標であり、中国、欧州連合、日本、英国で商標として登録されています。