Kontenery przestrzenne wprowadzają do OpenXR okna wolumetryczne. Kontener przestrzenny, zdefiniowany przez rozszerzenia XR_EXT_spatial_container i XR_EXT_spatial_container_self_rendering w OpenXR 1.1, to zarządzany przez system region wolumetryczny 3D w przestrzeni użytkownika, w którym aplikacja renderuje treści 3D za pomocą standardowych warstw kompozycji OpenXR.
Tradycyjnie sesja OpenXR wymaga wyłącznego dostępu do całego pola widzenia użytkownika. Kontenery przestrzenne umożliwiają aplikacji renderowanie treści 3D OpenXR w ograniczonym polu 3D w środowisku użytkownika lub przechodzenie w dowolnym momencie do nieograniczonego, pełnoekranowego trybu immersyjnego.
Informacje o kontenerach przestrzennych
Kontener przestrzenny to ograniczony lub nieograniczony region 3D zarządzany przez system Android XR i renderowany przez aplikację OpenXR:
- Tryb ograniczony: aplikacja sugeruje wymiary 3D (szerokość, wysokość i głębokość w metrach), a system przydziela trójwymiarową ramkę ograniczającą w środowisku użytkownika. Aplikacja renderuje treści stereo 3D wewnątrz obszaru, a system przycina renderowane treści do granic pola 3D.
- Tryb imersji: kontener przestrzenny rozszerza się do nieskończonych granic, dzięki czemu aplikacja zajmuje całe pole widzenia użytkownika, podobnie jak tradycyjna sesja OpenXR na pełnym ekranie.
Jak użytkownicy wchodzą w interakcję z kontenerami przestrzennymi
System Android XR zarządza elementami sterującymi okna kontenera przestrzennego i jego umiejscowieniem w przestrzeni fizycznej, zapewniając spójny model interakcji w różnych aplikacjach:
- Przenoszenie i zmiana pozycji: użytkownicy mogą chwycić uchwyt systemowy kontenera przestrzennego za pomocą gestów dłoni (np. szczypania) lub kontrolerów ruchu, aby zmienić jego pozycję w przestrzeni 3D.
- Minimalizowanie i zamykanie: elementy sterujące okna systemowego umożliwiają użytkownikom minimalizowanie i zamykanie poszczególnych kontenerów przestrzennych. Gdy użytkownik zamknie kontener, system powiadomi aplikację, aby mogła zwolnić zasoby.
- Blokowanie na podłodze z wykorzystaniem rozpoznawania sceny: gdy aplikacja deklaruje i żąda uprawnienia
android.permission.SCENE_UNDERSTANDING_COARSE, system automatycznie włącza przyciąganie do powierzchni, dzięki czemu użytkownicy mogą umieszczać i blokować kontenery przestrzenne na fizycznej podłodze bez dodatkowej konfiguracji aplikacji, jak pokazano na rysunku 1 (pomarańczowy kontener terenu). - Bezpośrednia interakcja 3D: gdy kontener jest zaznaczony i interaktywny, użytkownicy mogą wchodzić w bezpośrednią interakcję z treściami 3D wewnątrz woluminu, korzystając ze śledzenia rąk, wzroku lub kontrolerów 6DoF.
- Przechodzenie między trybem ograniczonym a trybem imersji: użytkownik lub aplikacja może przełączać kontener między ograniczonym polem 3D a nieograniczonym widokiem imersji na pełnym ekranie bez ponownego uruchamiania sesji OpenXR.
- Tryb śledzenia w ruchu: ponieważ system kontroluje położenie przestrzeni współrzędnych każdego kontenera przestrzennego (
xrCreateSpatialContainerSpaceEXT), użytkownicy mogą włączyć tryb śledzenia w ustawieniach okna systemowego, aby ograniczony kontener 3D automatycznie podążał za nimi i pozostawał w ich polu widzenia, gdy się poruszają. Nie wymaga to żadnej dodatkowej konfiguracji w aplikacji.
Jak używać kontenerów przestrzennych na Androidzie XR
Podczas tworzenia aplikacji z kontenerami przestrzennymi zaprojektuj scenę wokół granic kontenera, zmian stanu i trybu mieszania tła.
Dostosowywanie treści 3D do granic kontenera
W trybie ograniczonym punkt początkowy (0, 0, 0) przestrzeni kontenera przestrzennego (xrCreateSpatialContainerSpaceEXT) znajduje się w środku ramki ograniczającej 3D.
System zarządza pozycją przestrzeni kontenera w środowisku użytkownika, dlatego aplikacja renderuje treści 3D względem (0, 0, 0), a system obsługuje zmianę pozycji użytkownika i tryb śledzenia. System przycina wszystkie elementy geometryczne renderowane poza szerokością, wysokością lub głębokością pola, dzięki czemu treści pozostają w przypisanej im objętości.
Aplikacja powinna nasłuchiwać zdarzeń zmiany granic ze środowiska wykonawczego i skalować lub zmieniać położenie sceny 3D, aby kluczowe treści mieściły się w bieżących wymiarach kontenera. Gdy kontener przechodzi w tryb imersji, granice stają się nieskończone i możesz przywrócić scenę do pełnej skali świata 1:1.
Reagowanie na zmiany stanu kontenera
Zamiast zarządzać widocznością i fokusem tylko na poziomie aplikacji, każdy kontener przestrzenny zgłasza swój stan, dzięki czemu aplikacja może odpowiednio reagować:
- Widoczność: wskazuje, czy kontener jest obecnie widoczny czy ukryty. Wstrzymaj animacje, dźwięk lub aktualizacje symulacji, gdy kontener jest ukryty. Aplikacja może też poprosić o wyświetlenie lub ukrycie kontenera.
- Interaktywność: wskazuje, czy kontener jest aktywny i czy odbiera dane wejściowe użytkownika ze śledzenia rąk, kontrolerów lub wzroku. Włącz lub wyłącz interaktywne wyróżnienia i obsługę danych wejściowych, gdy zmienia się zaznaczenie.
- Tryb granic: wskazuje, czy kontener jest obecnie w trybie
XR_SPATIAL_CONTAINER_BOUNDS_MODE_BOUNDED_EXT(przycięty do pola 3D) czyXR_SPATIAL_CONTAINER_BOUNDS_MODE_IMMERSIVE_EXT(nieograniczony pełny ekran). Zaktualizuj skalę sceny i przełączaj elementy wizualne środowiska (takie jak skyboxy lub passthrough) po zmianie trybu. Aplikacja może też w każdej chwili poprosić o przejście między trybem ograniczonym a trybem imersji.
Używanie przezroczystości z mieszaniem alfa w trybie ograniczonym
W trybie ograniczonym przezroczyste tło sprawia, że otoczenie użytkownika i inne okna pozostają widoczne wokół modeli 3D. Skonfiguruj aparat lub obszar wyświetlania z przezroczystym tłem i użyj trybu mieszania środowiska z mieszaniem alfa. Podczas przełączania się na tryb imersji możesz pozostawić włączony tryb passthrough lub przełączyć się na nieprzezroczyste środowisko skybox.
Sprawdzanie dostępności funkcji i konfigurowanie pliku manifestu
Kontenery przestrzenne wymagają urządzenia z Androidem XR obsługującego interfejs Spatial API na poziomie 4 lub wyższym. Zamiast sprawdzać poziom interfejsu Android API bezpośrednio, wyślij zapytanie do środowiska wykonawczego OpenXR, aby określić, czy kontenery przestrzenne są obsługiwane. W tym celu wywołaj xrEnumerateInstanceExtensionProperties, aby sprawdzić, czy dostępne są XR_EXT_spatial_container i XR_EXT_spatial_container_self_rendering, a następnie wywołaj xrGetSystemProperties z XrSystemSpatialContainerPropertiesEXT, aby sprawdzić supportsBounded i supportsImmersive.
Zanim utworzysz aplikację, która korzysta z kontenerów przestrzennych, skonfiguruj tryb uruchamiania aktywności i wszystkie uprawnienia związane z funkcjami w pliku AndroidManifest.xml.
Włączanie trybu pełnej przestrzeni w pliku AndroidManifest.xml
Kontenery przestrzenne wymagają trybu zarządzanego pełnej przestrzeni, nawet w przypadku samodzielnych aplikacji OpenXR. Tradycyjne aplikacje OpenXR działające na pełnym ekranie deklarują XR_ACTIVITY_START_MODE_FULL_SPACE_UNMANAGED, aby przejąć wyłączną kontrolę nad wyświetlaczem bez zarządzania oknami systemowymi. Z kolei aplikacja korzystająca z kontenerów przestrzennych polega na kompozytorze systemu Android XR do zarządzania ograniczonymi woluminami 3D, elementami sterującymi okna i rozmieszczeniem przestrzennym w trybie pełnej przestrzeni. Musi też ustawić android.window.PROPERTY_XR_ACTIVITY_START_MODE na 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>
Deklarowanie i proszenie o uprawnienia dotyczące konkretnych funkcji
Tworzenie i renderowanie podstawowego kontenera przestrzennego nie wymaga niebezpiecznych uprawnień w czasie działania aplikacji. Jednak niektóre funkcje wymagają zadeklarowania i poproszenia o odpowiednie uprawnienia Androida XR:
- Aby zablokować i zakotwiczyć kontener przestrzenny na fizycznej podłodze za pomocą rozpoznawania sceny, zadeklaruj i poproś o niebezpieczne uprawnienie
android.permission.SCENE_UNDERSTANDING_COARSEw czasie działania. - Aby śledzić pozycję głowy użytkownika w OpenXR, zadeklaruj i poproś o
android.permission.HEAD_TRACKING.
<uses-permission android:name="android.permission.HEAD_TRACKING" />
<uses-permission android:name="android.permission.SCENE_UNDERSTANDING_COARSE" />
Szczegółowe informacje o deklarowaniu i żądaniu niebezpiecznych uprawnień XR w czasie działania znajdziesz w artykule Uprawnienia XR.
Włączanie kontenerów przestrzennych w projekcie
Kontenery przestrzenne możesz tworzyć za pomocą Unity, Godota lub bezpośrednio za pomocą OpenXR w C++. Wybierz kartę, aby zobaczyć wymagania wstępne, konfigurację edytora i przykładowy kod dla preferowanego środowiska:
Unity
Wymagania wstępne
- Wersja Unity: Unity 6 w wersji 6000.0.58f2 lub nowszej.
- Konfiguracja projektu: wykonaj wszystkie czynności opisane w przewodniku Konfigurowanie projektu Unity.
- Pakiety Unity: zainstaluj pakiet Android XR Extensions for Unity w wersji 1.5.0 lub nowszej.
Konfigurowanie projektu
- Kliknij Edit > Project Settings > XR Plug-in Management > OpenXR (Edytuj > Ustawienia projektu > Zarządzanie wtyczkami XR > OpenXR).
- Kliknij Ustawienia obok opcji Android XR (rozszerzenia): zarządzanie sesjami i odznacz Immersive XR.
- Na liście OpenXR Feature Groups (Grupy funkcji OpenXR) włącz Spatial Container (Kontener przestrzenny).
Użyj XRSpatialContainerFeature w C#, aby wysyłać zapytania o granice, reagować na zdarzenia kontenera i przełączać się między trybem ograniczonym a trybem imersji:
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);
}
Pełne instrukcje konfigurowania projektu, pliku manifestu i uprawnień znajdziesz w artykule Korzystanie z kontenerów przestrzennych w Unity.
Godot
Wymagania wstępne
- Wersja Godot: Godot 4.8-dev lub nowsza.
- Konfiguracja projektu: wykonaj wszystkie czynności opisane w przewodniku Konfigurowanie projektu w silniku Godot.
- Wtyczka Godot OpenXR Vendors: zainstaluj wtyczkę Godot OpenXR Vendors w wersji 5.2 lub nowszej.
Konfigurowanie projektu
- Kliknij Project > Project Settings (Projekt > Ustawienia projektu), włącz Advanced Settings (Ustawienia zaawansowane) i otwórz General > XR > OpenXR > Extensions (Ogólne > XR > OpenXR > Rozszerzenia).
- W podsekcji Kontener przestrzenny wybierz Włączony i skonfiguruj Tryb granic oraz Granice.
- Kliknij Project > Export… > Android i wybierz Użyj funkcji eksperymentalnych w sekcji Funkcje Androida XR.
Użyj singletonu OpenXRSpatialContainerExtension w GDScript, aby reagować na zmiany granic i trybu kontenera:
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
)
Pełne ustawienia projektu, uprawnienia do eksportowania i przykłady GDScript znajdziesz w artykule Korzystanie z kontenerów przestrzennych w Godot.
OpenXR
Wymagania wstępne
- Wersja OpenXR: nagłówki OpenXR 1.1 z
XR_EXT_spatial_containeriXR_EXT_spatial_container_self_rendering. - Konfiguracja pliku manifestu: skonfiguruj plik manifestu aplikacji zgodnie z opisem w artykule Pierwsze kroki z OpenXR na Androidzie XR, używając
XR_ACTIVITY_START_MODE_FULL_SPACE_MANAGED.
Podczas tworzenia XrInstance włącz XR_EXT_spatial_container i XR_EXT_spatial_container_self_rendering, a następnie utwórz i wyrenderuj kontener przestrzenny:
// 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);
Zobacz też
- Używanie kontenerów przestrzennych w Unity
- Używanie kontenerów przestrzennych w Godot
- Informacje o uprawnieniach XR
OpenXR™ i logo OpenXR są znakami towarowymi należącymi do firmy The Khronos Group Inc. i są zarejestrowane jako znaki towarowe w Chinach, Japonii, Unii Europejskiej i Wielkiej Brytanii.