XR_EXT_spatial_anchor

Name String

XR_EXT_spatial_anchor

Typ rozszerzenia

Rozszerzenie instancji

Zarejestrowany numer wewnętrzny

763

Wersja

1

Stan ratyfikacji

Ratified

Zależności rozszerzeń i wersji

XR_EXT_spatial_entity

Twórcy

Nihav Jain, 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 bazuje na XR_EXT_spatial_entity i umożliwia aplikacjom tworzenie kotwic przestrzennych, czyli dowolnych punktów w środowisku fizycznym użytkownika, które będą następnie śledzone przez środowisko wykonawcze. Środowisko wykonawcze powinno następnie w razie potrzeby dostosowywać pozycję i orientację punktu początkowego kotwicy, niezależnie od wszystkich innych przestrzeni i kotwic, aby zachować pierwotne mapowanie na świat rzeczywisty.

Kotwica, która śledzi daną pozycję i orientację w XrSpatialContextEXT, jest reprezentowana jako element przestrzenny z komponentem XR_SPATIAL_COMPONENT_TYPE_ANCHOR_EXT (lub „który ma” ten komponent).

Zalety korzystania z kotwic

W miarę jak środowisko wykonawcze aktualizuje informacje o środowisku fizycznym użytkownika przez cały okres działania XrSpatialContextEXT, obiekty wirtualne mogą wydawać się oddalać od miejsca, w którym zostały umieszczone przez aplikację, co wpływa na realizm aplikacji i jakość wrażeń użytkownika. Tworząc kotwicę w pobliżu miejsca, w którym umieszczony jest obiekt wirtualny, a następnie zawsze renderując ten obiekt wirtualny względem jego kotwicy, aplikacja może zapewnić, że każdy obiekt wirtualny będzie wyglądał tak, jakby pozostawał w tej samej pozycji i orientacji w środowisku fizycznym. W przeciwieństwie do niektórych przestrzeni referencyjnych na kotwice nie ma wpływu ponowne centrowanie na poziomie systemu.

Obsługa środowiska wykonawczego

Jeśli środowisko wykonawcze obsługuje kotwice przestrzenne, musi to wskazać, wyliczając XR_SPATIAL_CAPABILITY_ANCHOR_EXT w xrEnumerateSpatialCapabilitiesEXT .

Konfiguracja

Struktura XrSpatialCapabilityConfigurationAnchorEXT jest zdefiniowana w ten sposób:

typedef struct XrSpatialCapabilityConfigurationAnchorEXT {
    XrStructureType                     type;
    const void*                         next;
    XrSpatialCapabilityEXT              capability;
    uint32_t                            enabledComponentCount;
    const XrSpatialComponentTypeEXT*    enabledComponents;
} XrSpatialCapabilityConfigurationAnchorEXT;

Opisy członków

  • type to XrStructureType tej struktury.
  • next to NULL lub wskaźnik do następnej struktury w łańcuchu struktur.
  • capability to XrSpatialCapabilityEXT .
  • enabledComponentCount to uint32_t opisujący liczbę elementów w tablicy enabledComponents.
  • enabledComponents to wskaźnik do tablicy XrSpatialComponentTypeEXT .

Aplikacje mogą włączyć funkcję przestrzenną XR_SPATIAL_CAPABILITY_ANCHOR_EXT, dodając wskaźnik do struktury XrSpatialCapabilityConfigurationAnchorEXT w XrSpatialContextCreateInfoEXT :: capabilityConfigs .

Środowisko wykonawcze musi zwrócić XR_ERROR_VALIDATION_FAILURE, jeśli capability nie jest XR_SPATIAL_CAPABILITY_ANCHOR_EXT .

Prawidłowe użycie (pośrednie)

Komponenty gwarantowane

Środowisko wykonawcze obsługujące XR_SPATIAL_CAPABILITY_ANCHOR_EXT musi udostępniać te komponenty przestrzenne jako gwarantowane komponenty wszystkich elementów utworzonych lub wykrytych przez tę funkcję oraz musi je wyliczać w xrEnumerateSpatialCapabilityComponentTypesEXT :

  • XR_SPATIAL_COMPONENT_TYPE_ANCHOR_EXT

Komponent kotwicy

Dane komponentu

XR_SPATIAL_COMPONENT_TYPE_ANCHOR_EXT używa do swoich danych struktury XrPosef, która określa pozycję i orientację kotwicy.

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

Struktura XrSpatialComponentAnchorListEXT jest zdefiniowana w ten sposób:

typedef struct XrSpatialComponentAnchorListEXT {
    XrStructureType    type;
    void*              next;
    uint32_t           locationCount;
    XrPosef*           locations;
} XrSpatialComponentAnchorListEXT;

Opisy członków

  • type to XrStructureType tej struktury.
  • next to NULL lub wskaźnik do następnej struktury w łańcuchu struktur.
  • locationCount to uint32_t opisujący liczbę elementów w tablicy locations.
  • locations to tablica XrPosef .

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

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

Prawidłowe użycie (pośrednie)

  • Rozszerzenie XR_EXT_spatial_anchor musi być włączone przed użyciem XrSpatialComponentAnchorListEXT.
  • type musi mieć wartość XR_TYPE_SPATIAL_COMPONENT_ANCHOR_LIST_EXT
  • next musi mieć wartość NULL lub być prawidłowym wskaźnikiem do następnej struktury w łańcuchu struktur
  • locations musi być wskaźnikiem do tablicy struktur locationCount XrPosef
  • Parametr locationCount musi być większy niż 0
Konfiguracja

Jeśli XR_SPATIAL_COMPONENT_TYPE_ANCHOR_EXT jest wymieniony w XrSpatialCapabilityComponentTypesEXT :: componentTypes dla danej funkcji, aplikacja może go włączyć, dodając element wyliczeniowy do listy XrSpatialCapabilityConfigurationBaseHeaderEXT :: enabledComponents struktury pochodnej XrSpatialCapabilityConfigurationBaseHeaderEXT funkcji, która obsługuje ten komponent.

Ten komponent nie wymaga żadnej specjalnej konfiguracji, aby można go było uwzględnić w łańcuchu XrSpatialCapabilityConfigurationBaseHeaderEXT :: next.

Tworzenie kotwicy przestrzennej

Funkcja xrCreateSpatialAnchorEXT jest zdefiniowana w ten sposób:

XrResult xrCreateSpatialAnchorEXT(
    XrSpatialContextEXT                         spatialContext,
    const XrSpatialAnchorCreateInfoEXT*         createInfo,
    XrSpatialEntityIdEXT*                       anchorEntityId,
    XrSpatialEntityEXT*                         anchorEntity);

Opisy parametrów

Aplikacja może utworzyć kotwicę przestrzenną za pomocą funkcji xrCreateSpatialAnchorEXT .

Aby uzyskać zaktualizowane dane komponentu dla kotwicy, podczas tworzenia zrzutu przekaż wartość z pola anchorEntity do XrSpatialUpdateSnapshotCreateInfoEXT :: entities. Aplikacja może używać anchorEntityId do jednoznacznej identyfikacji tej kotwicy w tablicy XrSpatialComponentDataQueryResultEXT :: entityIds podczas korzystania z xrQuerySpatialComponentDataEXT .

Środowisko wykonawcze musi zwracać XR_ERROR_VALIDATION_FAILURE z xrCreateSpatialAnchorEXT, jeśli XR_SPATIAL_CAPABILITY_ANCHOR_EXT nie skonfigurowano dla spatialContext . Informacje o konfigurowaniu XrSpatialContextEXT na potrzeby funkcji XR_SPATIAL_CAPABILITY_ANCHOR_EXT znajdziesz w sekcji Konfiguracja.

Kotwica reprezentowana przez anchorEntity jest ważna tylko przez okres ważności spatialContext lub do momentu, gdy aplikacja wywoła dla niej funkcję xrDestroySpatialEntityEXT (w zależności od tego, co nastąpi wcześniej). Inne rozszerzenia mogą oferować funkcje umożliwiające zachowanie nowo utworzonej kotwicy w wielu sesjach XrSession lub udostępnianie jej innym aplikacjom poza granicami procesu.

Nowo utworzona kotwica, dopóki nie zostanie usunięta, musi być możliwa do znalezienia w jej nadrzędnym kontekście przestrzennym. Oznacza to, że środowisko wykonawcze musi uwzględnić anchorEntityId w zrzucie utworzonym za pomocą xrCreateSpatialDiscoverySnapshotAsyncEXT dla spatialContext, jeśli kotwica pasuje do kryteriów wykrywania ustawionych w XrSpatialDiscoverySnapshotCreateInfoEXT . Nowo utworzony punkt zakotwiczenia może być też wykrywalny w innych kontekstach przestrzennych skonfigurowanych za pomocą XR_SPATIAL_CAPABILITY_ANCHOR_EXT, ale z innym XrSpatialEntityIdEXT, ponieważ dany XrSpatialEntityIdEXT jest unikalny dla swojego XrSpatialContextEXT .

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_POSE_INVALID
  • XR_ERROR_RUNTIME_FAILURE
  • XR_ERROR_SESSION_LOST
  • XR_ERROR_TIME_INVALID
  • XR_ERROR_VALIDATION_FAILURE
  • XR_ERROR_SPATIAL_ANCHOR_ATTACHABLE_COMPONENT_NOT_FOUND_ANDROID (jeśli włączona jest opcja XR_ANDROID_spatial_entity_bound_anchor)
  • XR_ERROR_SPATIAL_ENTITY_ID_INVALID_EXT (jeśli włączona jest opcja XR_ANDROID_spatial_entity_bound_anchor)

Struktura XrSpatialAnchorCreateInfoEXT jest zdefiniowana w ten sposób:

typedef struct XrSpatialAnchorCreateInfoEXT {
    XrStructureType    type;
    const void*        next;
    XrSpace            baseSpace;
    XrTime             time;
    XrPosef            pose;
} XrSpatialAnchorCreateInfoEXT;

Opisy członków

  • type to XrStructureType tej struktury.
  • next to NULL lub wskaźnik do następnej struktury w łańcuchu struktur.
  • baseSpace to XrSpace, w którym stosowany jest pose.
  • time to XrTime, w którym znajduje się baseSpace (i gdzie stosuje się pose).
  • pose to lokalizacja elementu zakotwiczonego.

Prawidłowe użycie (pośrednie)

Pozycja kotwicy zapytania

Po utworzeniu kotwicy środowisko wykonawcze powinno z czasem dostosowywać jej pozycję i orientację względem innych przestrzeni, aby zachować jak najlepsze dopasowanie do jej pierwotnej lokalizacji w świecie rzeczywistym, nawet jeśli zmieni to relację kotwicy z pierwotnym elementem XrSpatialAnchorCreateInfoEXT :: baseSpace używanym do jej inicjowania.

Aplikacja może używać funkcji xrCreateSpatialUpdateSnapshotEXT z XrSpatialEntityEXT kotwicy, aby utworzyć nowy XrSpatialSnapshotEXT, a następnie wysłać zapytanie do komponentu XR_SPATIAL_COMPONENT_TYPE_ANCHOR_EXT z tego zrzutu za pomocą funkcji xrQuerySpatialComponentDataEXT . Aplikacja może dodać XrSpatialComponentAnchorListEXT do XrSpatialComponentDataQueryResultEXT :: next, aby pobrać najnowsze dane o lokalizacji kotwic.

Środowisko wykonawcze może ustawić stan śledzenia nowo utworzonej kotwicy na XR_SPATIAL_ENTITY_TRACKING_STATE_PAUSED_EXT . Aplikacja musi odczytywać stan encji kotwicy podany w XrSpatialComponentDataQueryResultEXT :: entityStates i dane komponentu kotwicy encji tylko wtedy, gdy stan śledzenia to XR_SPATIAL_ENTITY_TRACKING_STATE_TRACKING_EXT .

Wskazówki dotyczące korzystania z kotwic

  • Pozycja każdej kotwicy jest dostosowywana niezależnie od innych kotwic i przestrzeni. Oddzielnie zakotwiczone obiekty wirtualne mogą przesuwać się lub obracać względem siebie, co może naruszać hierarchię przestrzenną w przypadkach, gdy te obiekty wirtualne powinny pozostać na miejscu względem siebie. W takich przypadkach aplikacja powinna używać tej samej kotwicy dla wszystkich obiektów wirtualnych, które nie poruszają się względem siebie.
  • Aplikacja powinna niszczyć wszystkie uchwyty XrSpatialEntityEXT kotwic, które nie są już używane, aby zwolnić zasoby, które środowisko wykonawcze może wykorzystywać do śledzenia tych kotwic.

Przykładowy kod

Konfigurowanie funkcji kotwicy

Poniższy przykład pokazuje, jak skonfigurować funkcję kotwicy podczas tworzenia kontekstu przestrzennego.

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

  std::vector<XrSpatialComponentTypeEXT> enabledComponents = {
    XR_SPATIAL_COMPONENT_TYPE_ANCHOR_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();
  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;
}

// ...
// Create spatial anchors and get their latest pose in the frame loop.
// ...

CHK_XR(xrDestroySpatialContextEXT(spatialContext));

Tworzenie kotwicy przestrzennej i pobieranie jej lokalizacji

Poniższy przykład pokazuje, jak utworzyć kotwicę przestrzenną i uzyskać jej pozycję w każdej klatce.

XrSpatialAnchorCreateInfoEXT createInfo{XR_TYPE_SPATIAL_ANCHOR_CREATE_INFO_EXT};
createInfo.baseSpace = localSpace;
createInfo.time = predictedDisplayTime;
createInfo.pose = {{0, 0, 0, 1}, {1, 1, 1}};

XrSpatialEntityIdEXT spatialAnchorEntityId;
XrSpatialEntityEXT spatialAnchorEntity;
CHK_XR(xrCreateSpatialAnchorEXT(spatialContext, &createInfo, &spatialAnchorEntityId, &spatialAnchorEntity));

auto updateAnchorLocation = [&](XrTime time) {
  // We want to get updated data for all components of the entities, so skip specifying componentTypes.
  XrSpatialUpdateSnapshotCreateInfoEXT snapshotCreateInfo{XR_TYPE_SPATIAL_UPDATE_SNAPSHOT_CREATE_INFO_EXT};
  snapshotCreateInfo.entityCount = 1;
  snapshotCreateInfo.entities = &spatialAnchorEntity;
  snapshotCreateInfo.baseSpace = localSpace;
  snapshotCreateInfo.time = time;

  XrSpatialSnapshotEXT snapshot;
  CHK_XR(xrCreateSpatialUpdateSnapshotEXT(spatialContext, &snapshotCreateInfo, &snapshot));

  // Query for the entities that have the anchor component on them.
  std::array<XrSpatialComponentTypeEXT, 1> componentsToQuery {XR_SPATIAL_COMPONENT_TYPE_ANCHOR_EXT};
  XrSpatialComponentDataQueryConditionEXT queryCond{XR_TYPE_SPATIAL_COMPONENT_DATA_QUERY_CONDITION_EXT};
  queryCond.componentTypeCount = componentsToQuery.size();
  queryCond.componentTypes = componentsToQuery.data();

  XrSpatialComponentDataQueryResultEXT queryResult{XR_TYPE_SPATIAL_COMPONENT_DATA_QUERY_RESULT_EXT};
  CHK_XR(xrQuerySpatialComponentDataEXT(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();

  // query for the pose data
  std::vector<XrPosef> locations(queryResult.entityIdCountOutput);
  XrSpatialComponentAnchorListEXT locationList{XR_TYPE_SPATIAL_COMPONENT_ANCHOR_LIST_EXT};
  locationList.locationCount = locations.size();
  locationList.locations = locations.data();
  queryResult.next = &locationList;

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

  for (int32_t i = 0; i < queryResult.entityIdCountOutput; ++i) {
    if (entityStates[i] == XR_SPATIAL_ENTITY_TRACKING_STATE_TRACKING_EXT) {
      // Pose for entity entityIds[i] is locations[i].
    }
  }

  CHK_XR(xrDestroySpatialSnapshotEXT(snapshot));
};


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

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

  updateAnchorLocation(time);

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

CHK_XR(xrDestroySpatialEntityEXT(spatialAnchorEntity));

Nowe polecenia

Nowe domy

Nowe stałe typu wyliczeniowego

  • XR_EXT_SPATIAL_ANCHOR_EXTENSION_NAME
  • XR_EXT_spatial_anchor_SPEC_VERSION
  • Rozszerzenie XrSpatialCapabilityEXT :

    • XR_SPATIAL_CAPABILITY_ANCHOR_EXT
  • Rozszerzenie XrSpatialComponentTypeEXT :

    • XR_SPATIAL_COMPONENT_TYPE_ANCHOR_EXT
  • Rozszerzanie XrStructureType :

    • XR_TYPE_SPATIAL_ANCHOR_CREATE_INFO_EXT
    • XR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_ANCHOR_EXT
    • XR_TYPE_SPATIAL_COMPONENT_ANCHOR_LIST_EXT

Problemy

Historia zmian

  • Wersja 1, 10.07.2024 (Nihav Jain, Google)

    • Początkowy opis rozszerzenia