XR_EXT_spatial_anchor

Name String

XR_EXT_spatial_anchor

Extension Type

Instance extension

Registered Extension Number

763

Revision

1

Ratification Status

Ratified

Extension and Version Dependencies

XR_EXT_spatial_entity

Contributors

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 fizycznym otoczeniu użytkownika, które będą śledzone przez środowisko wykonawcze. Środowisko wykonawcze powinno w razie potrzeby dostosowywać pozycję i orientację początku kotwicy w czasie, niezależnie od innych przestrzeni i kotwic, aby zachować jej pierwotne mapowanie do świata rzeczywistego.

Kotwica, która śledzi daną pozycję i orientację w XrSpatialContextEXT, jest reprezentowana jako element przestrzenny z komponentem XR_SPATIAL_COMPONENT_TYPE_ANCHOR_EXT.

Zalety korzystania z kotwic

W miarę jak środowisko wykonawcze aktualizuje informacje o fizycznym otoczeniu użytkownika w trakcie działania XrSpatialContextEXT, obiekty wirtualne mogą się przesuwać względem 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 renderując ten obiekt wirtualny względem jego kotwicy, aplikacja może zapewnić, że każdy obiekt wirtualny będzie znajdował się w tej samej pozycji i orientacji w środowisku fizycznym. W przeciwieństwie do niektórych przestrzeni odniesienia kotwice nie są też narażone na ponowne wyśrodkowanie na poziomie systemu.

Obsługa środowiska wykonawczego

Jeśli środowisko wykonawcze obsługuje kotwice przestrzenne, musi to wskazać, wymieniają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 elementó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 .

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

Prawidłowe użycie (pośrednie)

Gwarantowane komponenty

Środowisko wykonawcze, które obsługuje XR_SPATIAL_CAPABILITY_ANCHOR_EXT musi udostępniać te komponenty przestrzenne jako gwarantowane komponenty wszystkich elementów utworzonych lub wykrytych przez tę funkcję i musi je wymieniać w xrEnumerateSpatialCapabilityComponentTypesEXT :

  • XR_SPATIAL_COMPONENT_TYPE_ANCHOR_EXT

Komponent kotwicy

Dane komponentu

XR_SPATIAL_COMPONENT_TYPE_ANCHOR_EXT używa XrPosef do przechowywania danych, które określają 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 elementó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 .

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 zwrócić XR_ERROR_VALIDATION_FAILURE z xrQuerySpatialComponentDataEXT .

Jeśli locationCount jest mniejsza niż XrSpatialComponentDataQueryResultEXT :: entityIdCountOutput, środowisko wykonawcze musi zwrócić XR_ERROR_SIZE_INSUFFICIENT z xrQuerySpatialComponentDataEXT .

Prawidłowe użycie (pośrednie)

Konfiguracja

Jeśli XR_SPATIAL_COMPONENT_TYPE_ANCHOR_EXT jest wymieniony w XrSpatialCapabilityComponentTypesEXT :: componentTypes dla jakiejś funkcji, aplikacja może go włączyć, dodając wyliczenie do listy XrSpatialCapabilityConfigurationBaseHeaderEXT :: enabledComponents w strukturze 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ą xrCreateSpatialAnchorEXT .

Aby uzyskać zaktualizowane dane komponentu kotwicy, podczas tworzenia migawki przekaż wartość wypełnioną w anchorEntity do XrSpatialUpdateSnapshotCreateInfoEXT :: entities. Aplikacja może użyć anchorEntityId, aby jednoznacznie zidentyfikować tę kotwicę w tablicy XrSpatialComponentDataQueryResultEXT :: entityIds podczas korzystania z xrQuerySpatialComponentDataEXT .

Jeśli XR_SPATIAL_CAPABILITY_ANCHOR_EXT nie został skonfigurowany dla spatialContext, środowisko wykonawcze musi zwrócić XR_ERROR_VALIDATION_FAILURE z xrCreateSpatialAnchorEXT . Informacje o tym, jak skonfigurować XrSpatialContextEXT dla funkcji XR_SPATIAL_CAPABILITY_ANCHOR_EXT, znajdziesz w sekcji Konfiguracja.

Kotwica reprezentowana przez anchorEntity jest ważna tylko przez czas działania spatialContext lub do momentu , gdy aplikacja wywoła dla niej xrDestroySpatialEntityEXT – w zależności od tego, co nastąpi wcześniej. Inne rozszerzenia mogą oferować funkcje umożliwiające zachowanie tej nowo utworzonej kotwicy w wielu sesjach XrSession lub udostępnianie jej między procesami innym aplikacjom.

Nowo utworzona kotwica, dopóki nie zostanie zniszczona, musi być wykrywalna w swoim nadrzędnym kontekście przestrzennym. Oznacza to, że jeśli kotwica pasuje do kryteriów wykrywania ustawionych w XrSpatialDiscoverySnapshotCreateInfoEXT, środowisko wykonawcze musi uwzględnić anchorEntityId w migawce utworzonej za pomocą xrCreateSpatialDiscoverySnapshotAsyncEXT dla spatialContext . Nowo utworzona kotwica może być też wykrywalna w innych kontekstach przestrzennych skonfigurowanych za pomocą XR_SPATIAL_CAPABILITY_ANCHOR_EXT, ale z innym XrSpatialEntityIdEXT, ponieważ konkretny XrSpatialEntityIdEXT jest unikalny dla swojego XrSpatialContextEXT .

Prawidłowe użycie (pośrednie)

Kody powrotu

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łączone jest XR_ANDROID_spatial_entity_bound_anchor)
  • XR_ERROR_SPATIAL_ENTITY_ID_INVALID_EXT (jeśli włączone jest 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 elementó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 stosowana jest pose.
  • time to XrTime, w którym znajduje się baseSpace (i stosowana jest pose).
  • pose to lokalizacja elementu kotwicy.

Prawidłowe użycie (pośrednie)

Zapytanie o pozę kotwicy

Po utworzeniu kotwicy środowisko wykonawcze powinno dostosowywać jej pozycję i orientację w czasie względem innych przestrzeni, aby zachować jak najlepsze wyrównanie z jej pierwotną lokalizacją w świecie rzeczywistym, nawet jeśli zmienia to jej relację z pierwotnym XrSpatialAnchorCreateInfoEXT :: baseSpace używanym do jej inicjowania.

Aplikacja może użyć xrCreateSpatialUpdateSnapshotEXT z XrSpatialEntityEXT kotwicy, aby utworzyć nowy XrSpatialSnapshotEXT, a następnie wysłać zapytanie o komponent XR_SPATIAL_COMPONENT_TYPE_ANCHOR_EXT z tej migawki za pomocą 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 elementu kotwicy podany w XrSpatialComponentDataQueryResultEXT :: entityStates oraz dane komponentu kotwicy elementu tylko wtedy, gdy stan śledzenia to XR_SPATIAL_ENTITY_TRACKING_STATE_TRACKING_EXT .

Wytyczne dotyczące korzystania z kotwic

  • Poza każdej kotwicy dostosowuje się niezależnie od innych kotwic i przestrzeni. Obiekty wirtualne zakotwiczone oddzielnie mogą się przesuwać lub obracać względem siebie, co powoduje naruszenie hierarchii przestrzennej w przypadkach, gdy te obiekty wirtualne powinny pozostać w stałym położeniu 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

W tym przykładzie pokazujemy, 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

W tym przykładzie pokazujemy, jak utworzyć kotwicę przestrzenną i pobierać jej pozę 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 struktury

Nowe stałe wyliczeniowe

  • XR_EXT_SPATIAL_ANCHOR_EXTENSION_NAME
  • XR_EXT_spatial_anchor_SPEC_VERSION
  • Rozszerzanie XrSpatialCapabilityEXT :

    • XR_SPATIAL_CAPABILITY_ANCHOR_EXT
  • Rozszerzanie 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