Tworzenie za pomocą kontenerów przestrzennych

Odpowiednie urządzenia z XR
Te wskazówki pomogą Ci tworzyć treści na te typy urządzeń z XR.
Gogle XR
Przewodowe okulary XR

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.
3 kontenery przestrzenne działające jednocześnie w trybie pełnej przestrzeni: pomarańczowy kontener 3D z terenem zablokowanym na podłodze, niebieski model kaczki 3D z dołączonym interfejsem 2D i zielony kontener interfejsu 2D.
Rysunek 1. Kilka kontenerów przestrzennych w trybie pełnej przestrzeni: zablokowany na podłodze trójwymiarowy teren (po lewej), trójwymiarowa kaczka połączona z interfejsem 2D (w środku) i kontener interfejsu 2D (po prawej).

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.
Użytkownik wchodzi w interakcję z kaczką 3D w ograniczonym niebieskim kontenerze przestrzennym za pomocą śledzenia rąk.
Rysunek 2. Użytkownik wchodzi w interakcję z treściami 3D w ograniczonym kontenerze przestrzennym za pomocą śledzenia rąk.
  • 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.
Scena 3D z kaczką po przejściu z ograniczonego kontenera przestrzennego do nieograniczonego widoku immersyjnego na pełnym ekranie.
Rysunek 3. Kontener przestrzenny po przejściu z trybu ograniczonego do trybu imersji, który wypełnia pole widzenia użytkownika.
  • 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) czy XR_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_COARSE w 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

Konfigurowanie projektu

  1. Kliknij Edit > Project Settings > XR Plug-in Management > OpenXR (Edytuj > Ustawienia projektu > Zarządzanie wtyczkami XR > OpenXR).
  2. Kliknij Ustawienia obok opcji Android XR (rozszerzenia): zarządzanie sesjami i odznacz Immersive XR.
  3. 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

Konfigurowanie projektu

  1. 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).
  2. W podsekcji Kontener przestrzenny wybierz Włączony i skonfiguruj Tryb granic oraz Granice.
  3. 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

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ż


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.