XR_EXT_spatial_persistence

Name String

XR_EXT_spatial_persistence

Typ rozszerzenia

Rozszerzenie instancji

Zarejestrowany numer wewnętrzny

764

Wersja

1

Stan ratyfikacji

Ratified

Zależności rozszerzeń i wersji

XR_EXT_spatial_entity
oraz
XR_EXT_future

Twórcy

Nihav Jain, Google
Jared Finder, Google
Natalie Fleury, Meta
Yuichi Taguchi, Meta
Ron Bessems, Meta
Yin Li, Microsoft
Jimmy Alamparambil, ByteDance
Zhipeng Liu, ByteDance
Jun Yan, ByteDance

Przegląd

To rozszerzenie umożliwia aplikacjom wykrywanie i korelowanie elementów przestrzennych w ramach sesji aplikacji, sesji OpenXR i wielu kontekstów przestrzennych OpenXR w ramach sesji. Rozszerzenie XR_EXT_spatial_entity określa, że element w XrSpatialContextEXT jest reprezentowany przez XrSpatialEntityIdEXT . To rozszerzenie rozszerza tę koncepcję, ustalając, że encja, jeśli jest utrwalona, jest reprezentowana przez XrUuid w sesjach aplikacji i OpenXR, tzn. aplikacja może używać identyfikatora XrUuid dostarczonego przez to rozszerzenie do identyfikowania encji w różnych sesjach. To rozszerzenie zapewnia też przydatne pokrywanie się z rozszerzeniem XR_EXT_spatial_entity, co pozwala wykrywać trwałe encje w środowisku użytkownika i odpytywać ich dane składowe.

Kontekst trwałości przestrzennej

Tworzenie kontekstu trwałości przestrzennej

XR_DEFINE_HANDLE(XrSpatialPersistenceContextEXT)

Uchwyt XrSpatialPersistenceContextEXT reprezentuje połączenie z trwałym magazynem elementów przestrzennych.

Funkcja xrCreateSpatialPersistenceContextAsyncEXT jest zdefiniowana w ten sposób:

XrResult xrCreateSpatialPersistenceContextAsyncEXT(
    XrSession                                   session,
    const XrSpatialPersistenceContextCreateInfoEXT* createInfo,
    XrFutureEXT*                                future);

Opisy parametrów

  • session to XrSession, w której kontekst trwałości przestrzennej będzie aktywny.
  • createInfo to XrSpatialPersistenceContextCreateInfoEXT używany do określania parametrów kontekstu trwałości przestrzennej.
  • future to wskaźnik do XrFutureEXT .

Aplikacja może utworzyć uchwyt XrSpatialPersistenceContextEXT za pomocą funkcji xrCreateSpatialPersistenceContextAsyncEXT i skonfigurować zakres kontekstu trwałości w createInfo .

Środowisko wykonawcze musi zwracać XR_ERROR_SPATIAL_PERSISTENCE_SCOPE_UNSUPPORTED_EXT, jeśli XrSpatialPersistenceContextCreateInfoEXT :: scope nie jest wyliczany przez xrEnumerateSpatialPersistenceScopesEXT .

Jeśli środowisko wykonawcze wymusza system uprawnień do kontrolowania dostępu aplikacji do pamięci trwałej reprezentowanej przez XrSpatialPersistenceContextEXT, środowisko wykonawcze musi zwrócić XR_ERROR_PERMISSION_INSUFFICIENT, jeśli te uprawnienia nie zostały przyznane tej aplikacji.

Prawidłowe użycie (pośrednie)

Kody zwrotu

Sukces

  • XR_SUCCESS
  • XR_SESSION_LOSS_PENDING

Błąd

  • XR_ERROR_FUNCTION_UNSUPPORTED
  • XR_ERROR_HANDLE_INVALID
  • XR_ERROR_INSTANCE_LOST
  • XR_ERROR_LIMIT_REACHED
  • XR_ERROR_OUT_OF_MEMORY
  • XR_ERROR_RUNTIME_FAILURE
  • XR_ERROR_SESSION_LOST
  • XR_ERROR_SPATIAL_PERSISTENCE_SCOPE_UNSUPPORTED_EXT
  • XR_ERROR_VALIDATION_FAILURE

Struktura XrSpatialPersistenceContextCreateInfoEXT jest zdefiniowana w ten sposób:

typedef struct XrSpatialPersistenceContextCreateInfoEXT {
    XrStructureType                 type;
    const void*                     next;
    XrSpatialPersistenceScopeEXT    scope;
} XrSpatialPersistenceContextCreateInfoEXT;

Opisy członków

  • type to XrStructureType tej struktury.
  • next to NULL lub wskaźnik do następnej struktury w łańcuchu struktur. W podstawowym interfejsie OpenXR ani w tym rozszerzeniu nie zdefiniowano takich struktur.
  • scope to XrSpatialPersistenceScopeEXT, który definiuje zakres przechowywania kontekstu trwałości.

Struktura XrSpatialPersistenceContextCreateInfoEXT opisuje informacje potrzebne do utworzenia uchwytu XrSpatialPersistenceContextEXT.

Prawidłowe użycie (pośrednie)

typedef enum XrSpatialPersistenceScopeEXT {
    XR_SPATIAL_PERSISTENCE_SCOPE_SYSTEM_MANAGED_EXT = 1,
    XR_SPATIAL_PERSISTENCE_SCOPE_LOCAL_ANCHORS_EXT = 1000781000,
    XR_SPATIAL_PERSISTENCE_SCOPE_ANCHORS_FOR_CLOUD_SHARING_ANDROIDX1 = 1000808000,
    XR_SPATIAL_PERSISTENCE_SCOPE_MAX_ENUM_EXT = 0x7FFFFFFF
} XrSpatialPersistenceScopeEXT;

Wyliczenie XrSpatialPersistenceScopeEXT identyfikuje różne typy zakresów kontekstu trwałości.

Typy wyliczeniowe mają następujące znaczenie:

Opis typu wyliczeniowego

XR_SPATIAL_PERSISTENCE_SCOPE_SYSTEM_MANAGED_EXT

Zapewnia aplikacji dostęp tylko do odczytu (tzn. aplikacja nie może modyfikować magazynu powiązanego z tym zakresem) do elementów przestrzennych przechowywanych i zarządzanych przez system. Aplikacja może używać identyfikatora UUID w komponencie trwałości dla tego zakresu, aby korelować encje w różnych kontekstach przestrzennych i po ponownym uruchomieniu urządzenia.

XR_SPATIAL_PERSISTENCE_SCOPE_LOCAL_ANCHORS_EXT

Operacje trwałości i dostęp do danych są ograniczone do kotwic przestrzennych na tym samym urządzeniu, dla tego samego użytkownika i tej samej aplikacji (dodane przez rozszerzenie XR_EXT_spatial_persistence_operations)

XR_SPATIAL_PERSISTENCE_SCOPE_ANCHORS_FOR_CLOUD_SHARING_ANDROIDX1

Operacje trwałości i dostęp do danych są ograniczone do kotwic przestrzennych, które są własnością tego samego projektu w chmurze i są przez niego zarządzane. (dodane przez rozszerzenie XR_ANDROIDX1_spatial_anchor_cloud_sharing)

Funkcja xrEnumerateSpatialPersistenceScopesEXT jest zdefiniowana w ten sposób:

XrResult xrEnumerateSpatialPersistenceScopesEXT(
    XrInstance                                  instance,
    XrSystemId                                  systemId,
    uint32_t                                    persistenceScopeCapacityInput,
    uint32_t*                                   persistenceScopeCountOutput,
    XrSpatialPersistenceScopeEXT*               persistenceScopes);

Opisy parametrów

  • instance to uchwyt do XrInstance .
  • systemId to XrSystemId, którego zakresy trwałości przestrzennej zostaną wyliczone.
  • persistenceScopeCapacityInput to pojemność tablicy persistenceScopes lub 0, co oznacza prośbę o pobranie wymaganej pojemności.
  • persistenceScopeCountOutput to liczba zakresów trwałości lub wymagana pojemność, jeśli persistenceScopeCapacityInput jest niewystarczająca.
  • persistenceScopes to tablica XrSpatialPersistenceScopeEXT . Może mieć wartość NULL, jeśli persistenceScopeCapacityInput wynosi 0.
  • Szczegółowy opis pobierania wymaganego rozmiaru persistenceScopes znajdziesz w rozdziale Parametry rozmiaru bufora.

Aplikacja może wyświetlić listę zakresów trwałości przestrzennej obsługiwanych przez dany element XrSystemId za pomocą funkcji xrEnumerateSpatialPersistenceScopesEXT .

Prawidłowe użycie (pośrednie)

  • Rozszerzenie XR_EXT_spatial_persistence musi być włączone przed wywołaniem xrEnumerateSpatialPersistenceScopesEXT.
  • instance musi być prawidłowym uchwytem XrInstance
  • persistenceScopeCountOutput musi być wskaźnikiem do wartości uint32_t
  • Jeśli persistenceScopeCapacityInput nie jest równe 0 , persistenceScopes musi być wskaźnikiem do tablicy wartości persistenceScopeCapacityInput XrSpatialPersistenceScopeEXT

Kody zwrotu

Sukces

  • XR_SUCCESS

Błąd

  • XR_ERROR_FUNCTION_UNSUPPORTED
  • XR_ERROR_HANDLE_INVALID
  • XR_ERROR_INSTANCE_LOST
  • XR_ERROR_RUNTIME_FAILURE
  • XR_ERROR_SIZE_INSUFFICIENT
  • XR_ERROR_SYSTEM_INVALID
  • XR_ERROR_VALIDATION_FAILURE

Funkcja xrCreateSpatialPersistenceContextCompleteEXT jest zdefiniowana w ten sposób:

XrResult xrCreateSpatialPersistenceContextCompleteEXT(
    XrSession                                   session,
    XrFutureEXT                                 future,
    XrCreateSpatialPersistenceContextCompletionEXT* completion);

Opisy parametrów

xrCreateSpatialPersistenceContextCompleteEXT kończy operację asynchroniczną rozpoczętą przez xrCreateSpatialPersistenceContextAsyncEXT . Środowisko wykonawcze musi zwracać XR_ERROR_FUTURE_PENDING_EXT, jeśli future nie jest w stanie gotowości. Środowisko wykonawcze musi zwrócić XR_ERROR_FUTURE_INVALID_EXT, jeśli future zostało już ukończone lub anulowane.

Prawidłowe użycie (pośrednie)

Kody zwrotu

Sukces

  • XR_SUCCESS
  • XR_SESSION_LOSS_PENDING

Błąd

  • XR_ERROR_FUNCTION_UNSUPPORTED
  • XR_ERROR_FUTURE_INVALID_EXT
  • XR_ERROR_FUTURE_PENDING_EXT
  • XR_ERROR_HANDLE_INVALID
  • XR_ERROR_INSTANCE_LOST
  • XR_ERROR_LIMIT_REACHED
  • XR_ERROR_OUT_OF_MEMORY
  • XR_ERROR_RUNTIME_FAILURE
  • XR_ERROR_SESSION_LOST
  • XR_ERROR_VALIDATION_FAILURE

Struktura XrCreateSpatialPersistenceContextCompletionEXT jest zdefiniowana w ten sposób:

typedef struct XrCreateSpatialPersistenceContextCompletionEXT {
    XrStructureType                         type;
    void*                                   next;
    XrResult                                futureResult;
    XrSpatialPersistenceContextResultEXT    createResult;
    XrSpatialPersistenceContextEXT          persistenceContext;
} XrCreateSpatialPersistenceContextCompletionEXT;

Opisy członków

Kody zwrotu w przyszłości

Wartości futureResult:

Sukces

  • XR_SUCCESS
  • XR_SESSION_LOSS_PENDING

Błąd

  • XR_ERROR_RUNTIME_FAILURE
  • XR_ERROR_INSTANCE_LOST
  • XR_ERROR_SESSION_LOST
  • XR_ERROR_OUT_OF_MEMORY
  • XR_ERROR_LIMIT_REACHED
  • XR_ERROR_PERMISSION_INSUFFICIENT

Jeśli futureResult i createResult są kodami powodzenia, persistenceContext musi być prawidłowy. Jeśli persistenceContext jest prawidłowy, musi pozostać taki w cyklu życia xrCreateSpatialPersistenceContextAsyncEXT :: session lub do momentu, gdy aplikacja użyje xrDestroySpatialPersistenceContextEXT z persistenceContext (w zależności od tego, co nastąpi wcześniej).

Środowisko wykonawcze musi ustawić createResult tylko wtedy, gdy futureResult jest kodem powodzenia.

Prawidłowe użycie (pośrednie)

typedef enum XrSpatialPersistenceContextResultEXT {
    XR_SPATIAL_PERSISTENCE_CONTEXT_RESULT_SUCCESS_EXT = 0,
    XR_SPATIAL_PERSISTENCE_CONTEXT_RESULT_ENTITY_NOT_TRACKING_EXT = -1000781001,
    XR_SPATIAL_PERSISTENCE_CONTEXT_RESULT_PERSIST_UUID_NOT_FOUND_EXT = -1000781002,
    XR_SPATIAL_PERSISTENCE_CONTEXT_RESULT_LOCALIZATION_FAILURE_ANDROIDX1 = -1000808000,
    XR_SPATIAL_PERSISTENCE_CONTEXT_RESULT_MAP_FEATURE_INSUFFICIENT_ANDROIDX1 = -1000808001,
    XR_SPATIAL_PERSISTENCE_CONTEXT_RESULT_NETWORK_FAILURE_ANDROIDX1 = -1000808002,
    XR_SPATIAL_PERSISTENCE_CONTEXT_RESULT_NETWORK_TIMEOUT_ANDROIDX1 = -1000808003,
    XR_SPATIAL_PERSISTENCE_CONTEXT_RESULT_MAX_ENUM_EXT = 0x7FFFFFFF
} XrSpatialPersistenceContextResultEXT;

Wyliczenie XrSpatialPersistenceContextResultEXT identyfikuje różne typy kodów wyników operacji trwałości. Aplikacja nie zawsze ma kontrolę nad błędami podczas operacji trwałości, a to wyliczenie służy do przekazywania takich przypadków. Podobnie jak w przypadku XrResult kody sukcesu w wyliczeniu XrSpatialPersistenceContextResultEXT są wartościami nieujemnymi, a kody błędów są wartościami ujemnymi.

Typy wyliczeniowe mają następujące znaczenie:

Opis typu wyliczeniowego

XR_SPATIAL_PERSISTENCE_CONTEXT_RESULT_SUCCESS_EXT

Operacja kontekstu trwałości zakończyła się powodzeniem.

XR_SPATIAL_PERSISTENCE_CONTEXT_RESULT_ENTITY_NOT_TRACKING_EXT

Operacja utrwalania nie powiodła się, ponieważ środowisko wykonawcze nie mogło śledzić encji. (dodane przez rozszerzenie XR_EXT_spatial_persistence_operations)

XR_SPATIAL_PERSISTENCE_CONTEXT_RESULT_PERSIST_UUID_NOT_FOUND_EXT

Nie znaleziono podanego identyfikatora UUID w pamięci masowej. (dodane przez rozszerzenie XR_EXT_spatial_persistence_operations)

XR_SPATIAL_PERSISTENCE_CONTEXT_RESULT_LOCALIZATION_FAILURE_ANDROIDX1

Operacja utrwalania nie powiodła się, ponieważ nie udało się przeprowadzić lokalizacji. (dodane przez rozszerzenie XR_ANDROIDX1_spatial_anchor_cloud_sharing)

XR_SPATIAL_PERSISTENCE_CONTEXT_RESULT_MAP_FEATURE_INSUFFICIENT_ANDROIDX1

Operacja utrwalania nie powiodła się, ponieważ funkcja mapy lokalizacji jest niewystarczająca. (dodane przez rozszerzenie XR_ANDROIDX1_spatial_anchor_cloud_sharing)

XR_SPATIAL_PERSISTENCE_CONTEXT_RESULT_NETWORK_FAILURE_ANDROIDX1

Operacja utrwalania nie powiodła się z powodu błędu połączenia sieciowego. (dodane przez rozszerzenie XR_ANDROIDX1_spatial_anchor_cloud_sharing)

XR_SPATIAL_PERSISTENCE_CONTEXT_RESULT_NETWORK_TIMEOUT_ANDROIDX1

Operacja utrwalania nie powiodła się z powodu przekroczenia limitu czasu sieci. (dodane przez rozszerzenie XR_ANDROIDX1_spatial_anchor_cloud_sharing)

zniszczyć kontekst trwałości przestrzennej,

Funkcja xrDestroySpatialPersistenceContextEXT jest zdefiniowana w ten sposób:

XrResult xrDestroySpatialPersistenceContextEXT(
    XrSpatialPersistenceContextEXT              persistenceContext);

Opisy parametrów

Aplikacja może używać funkcji xrDestroySpatialPersistenceContextEXT, aby zwolnić uchwyt persistenceContext po zakończeniu zadań związanych z trwałością przestrzenną.

Środowisko wykonawcze nie może niszczyć zasobów bazowych dla persistenceContext, gdy wywoływana jest funkcja xrDestroySpatialPersistenceContextEXT, jeśli istnieją prawidłowe uchwyty XrSpatialContextEXT, z którymi persistenceContext został połączony za pomocą XrSpatialContextPersistenceConfigEXT . Dzieje się tak, ponieważ zasoby kontekstu trwałości są nadal używane przez kontekst przestrzenny do wykrywania trwałych elementów. Zniszczenie uchwytu kontekstu trwałości w takiej sytuacji powoduje tylko usunięcie dostępu aplikacji do tych zasobów.

Zasoby zniszczonego obiektu XrSpatialPersistenceContextEXT muszą zostać zwolnione, gdy wszystkie uchwyty XrSpatialContextEXT, z którymi był połączony kontekst trwałości, zostaną zniszczone.

Prawidłowe użycie (pośrednie)

Bezpieczeństwo wątków

  • Dostęp do persistenceContext i wszystkich uchwytów podrzędnych musi być synchronizowany zewnętrznie.

Kody zwrotu

Sukces

  • XR_SUCCESS

Błąd

  • XR_ERROR_FUNCTION_UNSUPPORTED
  • XR_ERROR_HANDLE_INVALID
  • XR_ERROR_RUNTIME_FAILURE

Wykrywanie trwałych encji

Komponent trwałości

Trwałe elementy przestrzenne zawierają komponent trwałości, który środowisko wykonawcze musi uwzględnić w migawkach wykrywania i aktualizacji, jeśli funkcja XR_SPATIAL_COMPONENT_TYPE_PERSISTENCE_EXT jest włączona podczas tworzenia XrSpatialContextEXT i uwzględniona w XrSpatialDiscoverySnapshotCreateInfoEXT :: componentTypes lub XrSpatialUpdateSnapshotCreateInfoEXT :: componentTypes .

Dane komponentu

Struktura XrSpatialPersistenceDataEXT jest zdefiniowana w ten sposób:

typedef struct XrSpatialPersistenceDataEXT {
    XrUuid                          persistUuid;
    XrSpatialPersistenceStateEXT    persistState;
} XrSpatialPersistenceDataEXT;

Opisy członków

Prawidłowe użycie (pośrednie)

typedef enum XrSpatialPersistenceStateEXT {
    XR_SPATIAL_PERSISTENCE_STATE_LOADED_EXT = 1,
    XR_SPATIAL_PERSISTENCE_STATE_NOT_FOUND_EXT = 2,
    XR_SPATIAL_PERSISTENCE_STATE_MAX_ENUM_EXT = 0x7FFFFFFF
} XrSpatialPersistenceStateEXT;

Wyliczenie XrSpatialPersistenceStateEXT identyfikuje różne stany trwałego identyfikatora UUID.

Typy wyliczeniowe mają następujące znaczenie:

Opis typu wyliczeniowego

XR_SPATIAL_PERSISTENCE_STATE_LOADED_EXT

Trwały identyfikator UUID został wczytany z pamięci.

XR_SPATIAL_PERSISTENCE_STATE_NOT_FOUND_EXT

Nie znaleziono trwałego identyfikatora UUID w pamięci masowej. Został on z niej usunięty lub nigdy w niej nie był.

Struktura listy komponentów do wysyłania zapytań o dane

Struktura XrSpatialComponentPersistenceListEXT jest zdefiniowana w ten sposób:

typedef struct XrSpatialComponentPersistenceListEXT {
    XrStructureType                 type;
    void*                           next;
    uint32_t                        persistDataCount;
    XrSpatialPersistenceDataEXT*    persistData;
} XrSpatialComponentPersistenceListEXT;

Opisy członków

  • type to XrStructureType tej struktury.
  • next to NULL lub wskaźnik do następnej struktury w łańcuchu struktur. W podstawowym interfejsie OpenXR ani w tym rozszerzeniu nie zdefiniowano takich struktur.
  • persistDataCount to uint32_t opisujący liczbę elementów w tablicy persistData.
  • persistData to tablica XrSpatialPersistenceDataEXT .

Środowisko wykonawcze musi zwracać XR_ERROR_VALIDATION_FAILURE z xrQuerySpatialComponentDataEXT, jeśli XrSpatialComponentPersistenceListEXT znajduje się w następnym łańcuchu XrSpatialComponentDataQueryResultEXT :: next, ale XR_SPATIAL_COMPONENT_TYPE_PERSISTENCE_EXT nie jest uwzględniony w XrSpatialComponentDataQueryConditionEXT :: componentTypes .

Środowisko wykonawcze musi zwracać XR_ERROR_SIZE_INSUFFICIENT z xrQuerySpatialComponentDataEXT, jeśli persistDataCount jest mniejsze niż XrSpatialComponentDataQueryResultEXT :: entityIdCountOutput .

W przeciwieństwie do innych komponentów środowisko wykonawcze musi ustawić dane dla XR_SPATIAL_COMPONENT_TYPE_PERSISTENCE_EXT niezależnie od XrSpatialEntityTrackingStateEXT .

Prawidłowe użycie (pośrednie)

Konfiguracja

Jeśli XR_SPATIAL_COMPONENT_TYPE_PERSISTENCE_EXT jest wymieniony w XrSpatialCapabilityComponentTypesEXT :: componentTypes dla danej funkcji, aplikacja może ją włączyć, dodając enum do listy XrSpatialCapabilityConfigurationBaseHeaderEXT :: enabledComponents. Ten komponent nie wymaga żadnej specjalnej konfiguracji, aby można go było uwzględnić w następnym łańcuchu XrSpatialCapabilityConfigurationBaseHeaderEXT . Jeśli aplikacja zawiera XR_SPATIAL_COMPONENT_TYPE_PERSISTENCE_EXT na liście włączonych komponentów, musi też zawierać XrSpatialContextPersistenceConfigEXT w następnym łańcuchu XrSpatialContextCreateInfoEXT. W przeciwnym razie środowisko wykonawcze musi zwrócić XR_ERROR_SPATIAL_CAPABILITY_CONFIGURATION_INVALID_EXT z xrCreateSpatialContextAsyncEXT.

Konfigurowanie kontekstu przestrzennego za pomocą kontekstów trwałości

Struktura XrSpatialContextPersistenceConfigEXT jest zdefiniowana w ten sposób:

typedef struct XrSpatialContextPersistenceConfigEXT {
    XrStructureType                          type;
    const void*                              next;
    uint32_t                                 persistenceContextCount;
    const XrSpatialPersistenceContextEXT*    persistenceContexts;
} XrSpatialContextPersistenceConfigEXT;

Opisy członków

  • type to XrStructureType tej struktury.
  • next to NULL lub wskaźnik do następnej struktury w łańcuchu struktur. W podstawowym interfejsie OpenXR ani w tym rozszerzeniu nie zdefiniowano takich struktur.
  • persistenceContextCount to uint32_t opisujący liczbę elementów w tablicy persistenceContexts.
  • persistenceContexts to tablica XrSpatialPersistenceContextEXT .

Aplikacja może dodać XrSpatialContextPersistenceConfigEXT do następnego łańcucha XrSpatialContextCreateInfoEXT . Spowoduje to skonfigurowanie utworzonego elementu XrSpatialContextEXT za pomocą persistenceContexts i umożliwi aplikacji wykrywanie elementów przestrzennych zapisanych w pamięci reprezentowanej przez uchwyty XrSpatialPersistenceContextEXT w persistenceContexts .

Prawidłowe użycie (pośrednie)

Utwórz zrzut wykrywania

Odkrywanie encji o określonych identyfikatorach UUID

Struktura XrSpatialDiscoveryPersistenceUuidFilterEXT jest zdefiniowana w ten sposób:

typedef struct XrSpatialDiscoveryPersistenceUuidFilterEXT {
    XrStructureType    type;
    const void*        next;
    uint32_t           persistedUuidCount;
    const XrUuid*      persistedUuids;
} XrSpatialDiscoveryPersistenceUuidFilterEXT;

Opisy członków

  • type to XrStructureType tej struktury.
  • next to NULL lub wskaźnik do następnej struktury w łańcuchu struktur. W podstawowym interfejsie OpenXR ani w tym rozszerzeniu nie zdefiniowano takich struktur.
  • persistedUuidCount to uint32_t opisujący liczbę elementów w tablicy persistedUuids
  • persistedUuids to tablica XrUuid .

Aplikacja może używać XrSpatialDiscoveryPersistenceUuidFilterEXT w następnym łańcuchu XrSpatialDiscoverySnapshotCreateInfoEXT, aby ograniczyć zakres operacji wykrywania tylko do encji, których trwałe identyfikatory UUID znajdują się w zbiorze identyfikatorów UUID podanych w persistedUuids .

Jeśli aplikacja dodaje XrSpatialDiscoveryPersistenceUuidFilterEXT w następnym łańcuchu XrSpatialDiscoverySnapshotCreateInfoEXT, ale xrCreateSpatialDiscoverySnapshotAsyncEXT :: spatialContext nie skonfigurowano z żadnym XrSpatialPersistenceContextEXT przy użyciu XrSpatialContextPersistenceConfigEXT, środowisko wykonawcze musi zwrócić XR_ERROR_VALIDATION_FAILURE z xrCreateSpatialDiscoverySnapshotAsyncEXT .

Środowisko wykonawcze musi traktować filtr XrSpatialDiscoveryPersistenceUuidFilterEXT jako warunek „AND” z innymi filtrami podanymi w XrSpatialDiscoverySnapshotCreateInfoEXT lub w następnym łańcuchu. Środowisko wykonawcze musi traktować tablicę persistedUuids jako warunek „LUB”, czyli filtrować encje, które mają dowolny z identyfikatorów UUID podanych w tej tablicy.

Środowisko wykonawcze musi zawierać 1 wpis w utworzonym zrzucie dla każdego identyfikatora UUID w persistedUuids, dla którego udało się określić stan XrSpatialPersistenceStateEXT w danym momencie.

  • Jeśli środowisko wykonawcze pomyślnie znajdzie identyfikator UUID w swojej pamięci, to:

    • Środowisko wykonawcze musi ustawić XrSpatialPersistenceStateEXT w XrSpatialPersistenceDataEXT tego elementu na XR_SPATIAL_PERSISTENCE_STATE_LOADED_EXT .
    • Środowisko wykonawcze musi zawierać prawidłowy element XrSpatialEntityIdEXT dla tej encji w utworzonym zrzucie.
    • Środowisko wykonawcze musi ustawić XrSpatialEntityTrackingStateEXT tego elementu na XR_SPATIAL_ENTITY_TRACKING_STATE_TRACKING_EXT, jeśli aktywnie śledzi element i ma prawidłowe dane dotyczące jego komponentów. W przeciwnym razie środowisko wykonawcze musi ustawić XrSpatialEntityTrackingStateEXT na XR_SPATIAL_ENTITY_TRACKING_STATE_PAUSED_EXT .
  • Jeśli środowisko wykonawcze ustali, że identyfikator UUID nie znajduje się w pamięci (niezależnie od tego, czy nigdy nie był w niej przechowywany, czy był, ale został usunięty), to:

  • Jeśli środowisko wykonawcze nie było w stanie określić, czy identyfikator UUID znajduje się w jego pamięci, nie może uwzględniać go w zrzucie.

Aplikacja może też używać XrSpatialDiscoveryPersistenceUuidFilterEXT w następnym łańcuchu XrSpatialComponentDataQueryConditionEXT, aby wysyłać zapytania o elementy o określonych identyfikatorach UUID w istniejących zrzutach. Jeśli w przypadku użycia z XrSpatialComponentDataQueryConditionEXT XrSpatialDiscoveryPersistenceUuidFilterEXT :: persistedUuids zawiera dowolny XrUuid, który nie znajduje się w XrSpatialSnapshotEXT , środowisko wykonawcze nie może uwzględniać wpisu dla tego XrUuid w wyniku zapytania. Kolejność (sekwencja) elementów w wyniku zapytania może nie odpowiadać kolejności identyfikatorów UUID podanych w XrSpatialDiscoveryPersistenceUuidFilterEXT :: persistedUuids . Aplikacja powinna zawierać XR_SPATIAL_COMPONENT_TYPE_PERSISTENCE_EXT w XrSpatialComponentDataQueryConditionEXT :: componentTypes i XrSpatialComponentPersistenceListEXT w następnym łańcuchu XrSpatialComponentDataQueryResultEXT, a następnie sprawdzić XrSpatialPersistenceDataEXT :: persistUuid każdego indeksu wyników zapytania, aby dowiedzieć się, któremu identyfikatorowi UUID odpowiada bieżący indeks wyników.

Prawidłowe użycie (pośrednie)

Odkrywanie wszystkich trwałych encji

Jeśli aplikacja używa funkcji xrCreateSpatialDiscoverySnapshotAsyncEXT bez XrSpatialDiscoveryPersistenceUuidFilterEXT i z XrSpatialContextEXT, który został skonfigurowany z XrSpatialPersistenceContextEXT, środowisko wykonawcze musi uwzględnić w utworzonym zrzucie te elementy, które są utrwalone w pamięci reprezentowanej przez XrSpatialPersistenceContextEXT i spełniają filtry podane w XrSpatialDiscoverySnapshotCreateInfoEXT . W przypadku tych podmiotów:

  • Środowisko wykonawcze musi ustawić XrSpatialPersistenceStateEXT w XrSpatialPersistenceDataEXT tego elementu na XR_SPATIAL_PERSISTENCE_STATE_LOADED_EXT .
  • Środowisko wykonawcze musi zawierać prawidłowy element XrSpatialEntityIdEXT dla tej encji w utworzonym zrzucie.
  • Środowisko wykonawcze musi ustawić XrSpatialEntityTrackingStateEXT tego elementu na XR_SPATIAL_ENTITY_TRACKING_STATE_TRACKING_EXT, jeśli aktywnie śledzi element i ma prawidłowe dane dotyczące jego komponentów. W przeciwnym razie środowisko wykonawcze musi ustawić XrSpatialEntityTrackingStateEXT na XR_SPATIAL_ENTITY_TRACKING_STATE_PAUSED_EXT .

Nowe typy obiektów

Nowe polecenia

Nowe domy

Nowe wartości w polu enum

Nowe stałe typu wyliczeniowego

  • XR_EXT_SPATIAL_PERSISTENCE_EXTENSION_NAME
  • XR_EXT_spatial_persistence_SPEC_VERSION
  • Rozszerzanie XrObjectType :

    • XR_OBJECT_TYPE_SPATIAL_PERSISTENCE_CONTEXT_EXT
  • Rozszerzenie XrResult :

    • XR_ERROR_SPATIAL_PERSISTENCE_SCOPE_UNSUPPORTED_EXT
  • Rozszerzenie XrSpatialComponentTypeEXT :

    • XR_SPATIAL_COMPONENT_TYPE_PERSISTENCE_EXT
  • Rozszerzanie XrStructureType :

    • XR_TYPE_CREATE_SPATIAL_PERSISTENCE_CONTEXT_COMPLETION_EXT
    • XR_TYPE_SPATIAL_COMPONENT_PERSISTENCE_LIST_EXT
    • XR_TYPE_SPATIAL_CONTEXT_PERSISTENCE_CONFIG_EXT
    • XR_TYPE_SPATIAL_DISCOVERY_PERSISTENCE_UUID_FILTER_EXT
    • XR_TYPE_SPATIAL_PERSISTENCE_CONTEXT_CREATE_INFO_EXT

Przykładowy kod

Tworzenie kontekstu trwałości

// Check if the required persistence scope supported
uint32_t scopeCount;
CHK_XR(xrEnumerateSpatialPersistenceScopesEXT(instance, systemId, 0, &scopeCount, nullptr));
std::vector<XrSpatialPersistenceScopeEXT> persistenceScopes(scopeCount);
CHK_XR(xrEnumerateSpatialPersistenceScopesEXT(instance, systemId, scopeCount, &scopeCount, persistenceScopes.data()));

if (std::find(persistenceScopes.begin(), persistenceScopes.end(), XR_SPATIAL_PERSISTENCE_SCOPE_SYSTEM_MANAGED_EXT) == persistenceScopes.end()) {
  return;
}

XrSpatialPersistenceContextEXT persistenceContext{};

XrSpatialPersistenceContextCreateInfoEXT persistenceContextCreateInfo{XR_TYPE_SPATIAL_PERSISTENCE_CONTEXT_CREATE_INFO_EXT};
persistenceContextCreateInfo.scope = XR_SPATIAL_PERSISTENCE_SCOPE_SYSTEM_MANAGED_EXT;
XrFutureEXT createContextFuture;
CHK_XR(xrCreateSpatialPersistenceContextAsyncEXT(session, &persistenceContextCreateInfo, &createContextFuture));

waitUntilReady(createContextFuture);

XrCreateSpatialPersistenceContextCompletionEXT completion{XR_TYPE_CREATE_SPATIAL_PERSISTENCE_CONTEXT_COMPLETION_EXT};
CHK_XR(xrCreateSpatialPersistenceContextCompleteEXT(session, createContextFuture, &completion));
if (completion.futureResult != XR_SUCCESS || completion.createResult != XR_SPATIAL_PERSISTENCE_CONTEXT_RESULT_SUCCESS_EXT) {
  return;
}

persistenceContext = completion.persistenceContext;

// ...
// Connect persistence context to a spatial context and discover persisted entities.
// ...

CHK_XR(xrDestroySpatialPersistenceContextEXT(persistenceContext));

Łączenie kontekstu trwałości z kontekstem przestrzennym

// Note: Anchor capability is just used as an example here. Persistence can be
// supported by other capabilities too. xrEnumerateSpatialCapabilityComponentTypesEXT() can
// be used to check if a certain capability supports persistence.
if (!isSpatialCapabilitySupported(instance, systemId, XR_SPATIAL_CAPABILITY_ANCHOR_EXT)) {
  return;
}

const bool supportsPersistenceComponent = isSpatialComponentSupported(instance, systemId, XR_SPATIAL_CAPABILITY_ANCHOR_EXT, XR_SPATIAL_COMPONENT_TYPE_PERSISTENCE_EXT);

// Create a spatial spatial context
XrSpatialContextEXT spatialContext{};
{

  std::vector<XrSpatialComponentTypeEXT> enabledComponents = {
    XR_SPATIAL_COMPONENT_TYPE_ANCHOR_EXT,
  };

  if (supportsPersistenceComponent) {
    enabledComponents.push_back(XR_SPATIAL_COMPONENT_TYPE_PERSISTENCE_EXT);
  }

  XrSpatialCapabilityConfigurationAnchorEXT anchorConfig{XR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_ANCHOR_EXT};
  anchorConfig.capability = XR_SPATIAL_CAPABILITY_ANCHOR_EXT;
  anchorConfig.enabledComponentCount = enabledComponents.size();
  anchorConfig.enabledComponents = enabledComponents.data();

  std::array<XrSpatialCapabilityConfigurationBaseHeaderEXT*, 1> capabilityConfigs = {
    reinterpret_cast<XrSpatialCapabilityConfigurationBaseHeaderEXT*>(&anchorConfig),
  };

  XrSpatialContextCreateInfoEXT spatialContextCreateInfo{XR_TYPE_SPATIAL_CONTEXT_CREATE_INFO_EXT};
  spatialContextCreateInfo.capabilityConfigCount = capabilityConfigs.size();
  spatialContextCreateInfo.capabilityConfigs = capabilityConfigs.data();

  XrSpatialContextPersistenceConfigEXT persistenceConfig{XR_TYPE_SPATIAL_CONTEXT_PERSISTENCE_CONFIG_EXT};
  persistenceConfig.persistenceContextCount = 1;
  persistenceConfig.persistenceContexts = &persistenceContext;

  if (supportsPersistenceComponent) {
    spatialContextCreateInfo.next = &persistenceConfig;
  }

  XrFutureEXT createContextFuture;
  CHK_XR(xrCreateSpatialContextAsyncEXT(session, &spatialContextCreateInfo, &createContextFuture));

  waitUntilReady(createContextFuture);

  XrCreateSpatialContextCompletionEXT completion{XR_TYPE_CREATE_SPATIAL_CONTEXT_COMPLETION_EXT};
  CHK_XR(xrCreateSpatialContextCompleteEXT(session, createContextFuture, &completion));
  if (completion.futureResult != XR_SUCCESS) {
    return;
  }

  spatialContext = completion.spatialContext;
}

// ...
// Discover persisted anchors.
// ...

CHK_XR(xrDestroySpatialContextEXT(spatialContext));

Odkrywanie wszystkich trwałych encji

XrFutureEXT future = XR_NULL_FUTURE_EXT;

// We want to look for entities that have the following components.
std::vector<XrSpatialComponentTypeEXT> snapshotComponents = {
  XR_SPATIAL_COMPONENT_TYPE_PERSISTENCE_EXT,
};

auto discoverSpatialEntities = [&](XrSpatialContextEXT spatialContext, XrTime time) {
  XrSpatialDiscoverySnapshotCreateInfoEXT snapshotCreateInfo{XR_TYPE_SPATIAL_DISCOVERY_SNAPSHOT_CREATE_INFO_EXT};
  snapshotCreateInfo.componentTypeCount = snapshotComponents.size();
  snapshotCreateInfo.componentTypes = snapshotComponents.data();
  CHK_XR(xrCreateSpatialDiscoverySnapshotAsyncEXT(spatialContext, &snapshotCreateInfo, &future));

  waitUntilReady(future);

  XrCreateSpatialDiscoverySnapshotCompletionInfoEXT completionInfo{XR_TYPE_CREATE_SPATIAL_DISCOVERY_SNAPSHOT_COMPLETION_INFO_EXT};
  completionInfo.baseSpace = localSpace;
  completionInfo.time = time;
  completionInfo.future = future;

  XrCreateSpatialDiscoverySnapshotCompletionEXT completion{XR_TYPE_CREATE_SPATIAL_DISCOVERY_SNAPSHOT_COMPLETION_EXT};
  CHK_XR(xrCreateSpatialDiscoverySnapshotCompleteEXT(spatialContext, &completionInfo, &completion));
  if (completion.futureResult == XR_SUCCESS) {

    // Query for the semantic label component data
    XrSpatialComponentDataQueryConditionEXT queryCond{XR_TYPE_SPATIAL_COMPONENT_DATA_QUERY_CONDITION_EXT};
    queryCond.componentTypeCount = snapshotComponents.size();
    queryCond.componentTypes = snapshotComponents.data();

    XrSpatialComponentDataQueryResultEXT queryResult{XR_TYPE_SPATIAL_COMPONENT_DATA_QUERY_RESULT_EXT};
    CHK_XR(xrQuerySpatialComponentDataEXT(completion.snapshot, &queryCond, &queryResult));

    std::vector<XrSpatialEntityIdEXT> entityIds(queryResult.entityIdCountOutput);
    std::vector<XrSpatialEntityTrackingStateEXT> entityStates(queryResult.entityIdCountOutput);
    queryResult.entityIdCapacityInput = entityIds.size();
    queryResult.entityIds = entityIds.data();
    queryResult.entityStateCapacityInput = entityStates.size();
    queryResult.entityStates = entityStates.data();

    std::vector<XrSpatialPersistenceDataEXT> persistenceData(queryResult.entityIdCountOutput);
    XrSpatialComponentPersistenceListEXT persistenceDataList{XR_TYPE_SPATIAL_COMPONENT_PERSISTENCE_LIST_EXT};
    persistenceDataList.persistDataCount = persistenceData.size();
    persistenceDataList.persistData = persistenceData.data();
    queryResult.next = &persistenceDataList;

    CHK_XR(xrQuerySpatialComponentDataEXT(completion.snapshot, &queryCond, &queryResult));

    for (int32_t i = 0; i < queryResult.entityIdCountOutput; ++i) {
      // persistenceData[i].persistUuid is the UUID of the persisted entity whose entity ID is entityIds[i].
      // The persistenceData array is essentially the uuids persisted in the scope that the current
      // XrSpatialPersistenceContextEXT is configured with.
    }

    CHK_XR(xrDestroySpatialSnapshotEXT(completion.snapshot));
  }
};

while (1) {
  // ...
  // For every frame in frame loop
  // ...

  XrFrameState frameState;  // previously returned from xrWaitFrame
  const XrTime time = frameState.predictedDisplayTime;

  // Poll for the XR_TYPE_EVENT_DATA_SPATIAL_DISCOVERY_RECOMMENDED_EXT event
  XrEventDataBuffer event = {XR_TYPE_EVENT_DATA_BUFFER};
  XrResult result = xrPollEvent(instance, &event);
  if (result == XR_SUCCESS) {
      switch (event.type) {
          case XR_TYPE_EVENT_DATA_SPATIAL_DISCOVERY_RECOMMENDED_EXT: {
              const XrEventDataSpatialDiscoveryRecommendedEXT& eventdata =
                  *reinterpret_cast<XrEventDataSpatialDiscoveryRecommendedEXT*>(&event);
              // Discover spatial entities for the context that we received the "discovery
              // recommended" event for.
              discoverSpatialEntities(eventdata.spatialContext, time);
              break;
          }
      }
  }

  // ...
  // Finish frame loop
  // ...
}

Odkrywanie encji o określonych identyfikatorach UUID

XrFutureEXT future = XR_NULL_FUTURE_EXT;

// Load up the uuids that the app has stored on its own i.e. the uuids it is interested in.
std::vector<XrUuid> uuidsStoredByApp = loadPersistedUuids();

// We want to look for entities that have the following components.
std::vector<XrSpatialComponentTypeEXT> snapshotComponents = {
  XR_SPATIAL_COMPONENT_TYPE_PERSISTENCE_EXT,
};

auto discoverSpatialEntities = [&](XrSpatialContextEXT spatialContext, XrTime time) {
  XrSpatialDiscoveryPersistenceUuidFilterEXT persistenceFilter{XR_TYPE_SPATIAL_DISCOVERY_PERSISTENCE_UUID_FILTER_EXT};
  persistenceFilter.persistedUuidCount = uuidsStoredByApp.size();
  persistenceFilter.persistedUuids = uuidsStoredByApp.data();

  XrSpatialDiscoverySnapshotCreateInfoEXT snapshotCreateInfo{XR_TYPE_SPATIAL_DISCOVERY_SNAPSHOT_CREATE_INFO_EXT};
  snapshotCreateInfo.componentTypeCount = snapshotComponents.size();
  snapshotCreateInfo.componentTypes = snapshotComponents.data();
  snapshotCreateInfo.next = &persistenceFilter;

  CHK_XR(xrCreateSpatialDiscoverySnapshotAsyncEXT(spatialContext, &snapshotCreateInfo, &future));

  waitUntilReady(future);

  XrCreateSpatialDiscoverySnapshotCompletionInfoEXT completionInfo{XR_TYPE_CREATE_SPATIAL_DISCOVERY_SNAPSHOT_COMPLETION_INFO_EXT};
  completionInfo.baseSpace = localSpace;
  completionInfo.time = time;
  completionInfo.future = future;

  XrCreateSpatialDiscoverySnapshotCompletionEXT completion{XR_TYPE_CREATE_SPATIAL_DISCOVERY_SNAPSHOT_COMPLETION_EXT};
  CHK_XR(xrCreateSpatialDiscoverySnapshotCompleteEXT(spatialContext, &completionInfo, &completion));
  if (completion.futureResult == XR_SUCCESS) {

    // Query for the semantic label component data
    XrSpatialComponentDataQueryConditionEXT queryCond{XR_TYPE_SPATIAL_COMPONENT_DATA_QUERY_CONDITION_EXT};
    queryCond.componentTypeCount = snapshotComponents.size();
    queryCond.componentTypes = snapshotComponents.data();

    XrSpatialComponentDataQueryResultEXT queryResult{XR_TYPE_SPATIAL_COMPONENT_DATA_QUERY_RESULT_EXT};
    CHK_XR(xrQuerySpatialComponentDataEXT(completion.snapshot, &queryCond, &queryResult));

    std::vector<XrSpatialEntityIdEXT> entityIds(queryResult.entityIdCountOutput);
    std::vector<XrSpatialEntityTrackingStateEXT> entityStates(queryResult.entityIdCountOutput);
    queryResult.entityIdCapacityInput = entityIds.size();
    queryResult.entityIds = entityIds.data();
    queryResult.entityStateCapacityInput = entityStates.size();
    queryResult.entityStates = entityStates.data();

    std::vector<XrSpatialPersistenceDataEXT> persistenceData(queryResult.entityIdCountOutput);
    XrSpatialComponentPersistenceListEXT persistenceDataList{XR_TYPE_SPATIAL_COMPONENT_PERSISTENCE_LIST_EXT};
    persistenceDataList.persistDataCount = persistenceData.size();
    persistenceDataList.persistData = persistenceData.data();
    queryResult.next = &persistenceDataList;

    CHK_XR(xrQuerySpatialComponentDataEXT(completion.snapshot, &queryCond, &queryResult));

    for (int32_t i = 0; i < queryResult.entityIdCountOutput; ++i) {
      if (persistenceData[i].persistState == XR_SPATIAL_PERSISTENCE_STATE_LOADED_EXT) {
        // persistenceData[i].persistUuid, requested by the app, is present in the persistence scope
        // and its corresponding entity ID and state are entityIds[i] & entityStates[i] respectively.
      } else if (persistenceData[i].persistState == XR_SPATIAL_PERSISTENCE_STATE_NOT_FOUND_EXT) {
        // persistenceData[i].persistUuid, requested by the app, is NOT present in the persistence scope
        // and its corresponding entity ID (entityIds[i]) would be XR_NULL_SPATIAL_ENTITY_ID_EXT
        // and tracking state (entityStates[i]) would be XR_SPATIAL_ENTITY_TRACKING_STATE_STOPPED_EXT.
      }
    }

    CHK_XR(xrDestroySpatialSnapshotEXT(completion.snapshot));
  }
};

while (1) {
  // ...
  // For every frame in frame loop
  // ...

  XrFrameState frameState;  // previously returned from xrWaitFrame
  const XrTime time = frameState.predictedDisplayTime;

  // Poll for the XR_TYPE_EVENT_DATA_SPATIAL_DISCOVERY_RECOMMENDED_EXT event
  XrEventDataBuffer event = {XR_TYPE_EVENT_DATA_BUFFER};
  XrResult result = xrPollEvent(instance, &event);
  if (result == XR_SUCCESS) {
      switch (event.type) {
          case XR_TYPE_EVENT_DATA_SPATIAL_DISCOVERY_RECOMMENDED_EXT: {
              const XrEventDataSpatialDiscoveryRecommendedEXT& eventdata =
                  *reinterpret_cast<XrEventDataSpatialDiscoveryRecommendedEXT*>(&event);
              // Discover spatial entities for the context that we received the "discovery
              // recommended" event for.
              discoverSpatialEntities(eventdata.spatialContext, time);
              break;
          }
      }
  }

  // ...
  // Finish frame loop
  // ...
}

Problemy

Historia zmian

  • Wersja 1, 29 sierpnia 2024 r. (Nihav Jain, Google)

    • Początkowy opis rozszerzenia