XR_EXT_spatial_persistence

Name String

XR_EXT_spatial_persistence

Erweiterungstyp

Instanzerweiterung

Registrierte Durchwahl

764

Revision

1

Ratification Status

Ratified

Erweiterungs- und Versionsabhängigkeiten

XR_EXT_spatial_entity
und
XR_EXT_future

Mitwirkende

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

Übersicht

Mit dieser Erweiterung können Anwendungen räumliche Entitäten über Anwendungssitzungen, OpenXR-Sitzungen und mehrere OpenXR-räumliche Kontexte innerhalb einer Sitzung hinweg erkennen und korrelieren. Die Erweiterung XR_EXT_spatial_entity legt fest, dass eine Entität innerhalb eines XrSpatialContextEXT durch ein XrSpatialEntityIdEXT dargestellt wird. Diese Erweiterung baut auf diesem Konzept auf, indem sie festlegt, dass eine Entität, wenn sie beibehalten wird, über Anwendungs- und OpenXR-Sitzungen hinweg durch eine XrUuid dargestellt wird. Das bedeutet, dass eine Anwendung die von dieser Erweiterung bereitgestellte XrUuid verwenden kann, um eine Entität über Sitzungen hinweg zu identifizieren. Diese Erweiterung bietet auch nützliche Überschneidungen mit der Erweiterung XR_EXT_spatial_entity, um persistente Entitäten in der Umgebung des Nutzers zu finden und ihre Komponentendaten abzufragen.

Spatial Persistence Context

Kontext für räumliche Persistenz erstellen

XR_DEFINE_HANDLE(XrSpatialPersistenceContextEXT)

Das Handle XrSpatialPersistenceContextEXT stellt die Verbindung zu einem persistenten Speicher für räumliche Entitäten dar.

Die Funktion xrCreateSpatialPersistenceContextAsyncEXT ist so definiert:

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

Parameterbeschreibungen

  • session ist eine XrSession, in der der Kontext für die räumliche Persistenz aktiv ist.
  • createInfo ist die XrSpatialPersistenceContextCreateInfoEXT, mit der die Parameter für den räumlichen Persistenzkontext angegeben werden.
  • future ist ein Zeiger auf ein XrFutureEXT .

Eine Anwendung kann mit der Funktion xrCreateSpatialPersistenceContextAsyncEXT ein XrSpatialPersistenceContextEXT-Handle erstellen und den Bereich des Persistenzkontexts in createInfo konfigurieren.

Die Laufzeit muss XR_ERROR_SPATIAL_PERSISTENCE_SCOPE_UNSUPPORTED_EXT zurückgeben, wenn XrSpatialPersistenceContextCreateInfoEXT :: scope nicht von xrEnumerateSpatialPersistenceScopesEXT aufgezählt wird.

Wenn eine Laufzeit ein Berechtigungssystem erzwingt, um den Zugriff der Anwendung auf den durch XrSpatialPersistenceContextEXT dargestellten nichtflüchtigen Speicher zu steuern, muss die Laufzeit XR_ERROR_PERMISSION_INSUFFICIENT zurückgeben, wenn diese Berechtigungen der Anwendung nicht gewährt wurden.

Gültige Verwendung (implizit)

Rückgabecodes

Erfolg

  • XR_SUCCESS
  • XR_SESSION_LOSS_PENDING

Fehler

  • 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

Die Struktur XrSpatialPersistenceContextCreateInfoEXT ist so definiert:

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

Mitgliederbeschreibungen

  • type ist der XrStructureType dieser Struktur.
  • next ist NULL oder ein Zeiger auf die nächste Struktur in einer Strukturkette. Solche Strukturen sind weder in OpenXR noch in dieser Erweiterung definiert.
  • scope ist ein XrSpatialPersistenceScopeEXT, der den Speicherbereich des Persistenzkontexts definiert.

Die Struktur XrSpatialPersistenceContextCreateInfoEXT beschreibt die Informationen zum Erstellen eines XrSpatialPersistenceContextEXT-Handles.

Gültige Verwendung (implizit)

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;

Die Aufzählung XrSpatialPersistenceScopeEXT gibt die verschiedenen Arten von Persistenzkontextbereichen an.

Die Enums haben die folgenden Bedeutungen:

Enum-Beschreibung

XR_SPATIAL_PERSISTENCE_SCOPE_SYSTEM_MANAGED_EXT

Gewährt der Anwendung Lesezugriff auf räumliche Entitäten, die vom System beibehalten und verwaltet werden. Die Anwendung kann den mit diesem Bereich verknüpften Speicher nicht ändern. Die Anwendung kann die UUID in der Persistenzkomponente für diesen Bereich verwenden, um Entitäten über räumliche Kontexte und Geräteneustarts hinweg zu korrelieren.

XR_SPATIAL_PERSISTENCE_SCOPE_LOCAL_ANCHORS_EXT

Persistenzvorgänge und Datenzugriff sind auf räumliche Anker auf demselben Gerät, für denselben Nutzer und dieselbe App beschränkt (durch die XR_EXT_spatial_persistence_operations-Erweiterung hinzugefügt)

XR_SPATIAL_PERSISTENCE_SCOPE_ANCHORS_FOR_CLOUD_SHARING_ANDROIDX1

Persistenzvorgänge und der Datenzugriff sind auf Raumanker beschränkt, die zum selben Cloud-Projekt gehören und von diesem verwaltet werden. (Hinzugefügt durch die Erweiterung „XR_ANDROIDX1_spatial_anchor_cloud_sharing“)

Die Funktion xrEnumerateSpatialPersistenceScopesEXT ist so definiert:

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

Parameterbeschreibungen

  • instance ist ein Handle für eine XrInstance .
  • systemId ist der XrSystemId, dessen räumliche Persistenzbereiche aufgezählt werden.
  • persistenceScopeCapacityInput ist die Kapazität des persistenceScopes-Arrays oder 0, um eine Anfrage zum Abrufen der erforderlichen Kapazität anzugeben.
  • persistenceScopeCountOutput ist die Anzahl der Persistenzbereiche oder die erforderliche Kapazität, falls persistenceScopeCapacityInput nicht ausreicht.
  • persistenceScopes ist ein Array von XrSpatialPersistenceScopeEXT . Er kann NULL sein, wenn persistenceScopeCapacityInput 0 ist.
  • Eine ausführliche Beschreibung zum Abrufen der erforderlichen persistenceScopes-Größe finden Sie im Kapitel Parameter für die Puffergröße.

Die Anwendung kann die Liste der räumlichen Persistenzbereiche, die von einer bestimmten XrSystemId unterstützt werden, mit xrEnumerateSpatialPersistenceScopesEXT aufzählen.

Gültige Verwendung (implizit)

  • Die Erweiterung XR_EXT_spatial_persistence muss aktiviert werden, bevor xrEnumerateSpatialPersistenceScopesEXT aufgerufen wird.
  • instance muss ein gültiges XrInstance-Handle sein
  • persistenceScopeCountOutput muss ein Zeiger auf einen uint32_t-Wert sein
  • Wenn persistenceScopeCapacityInput nicht 0 ist, muss persistenceScopes ein Zeiger auf ein Array von persistenceScopeCapacityInput XrSpatialPersistenceScopeEXT-Werten sein.

Rückgabecodes

Erfolg

  • XR_SUCCESS

Fehler

  • 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

Die Funktion xrCreateSpatialPersistenceContextCompleteEXT ist so definiert:

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

Parameterbeschreibungen

xrCreateSpatialPersistenceContextCompleteEXT schließt den asynchronen Vorgang ab, der von xrCreateSpatialPersistenceContextAsyncEXT gestartet wurde. Die Laufzeit muss XR_ERROR_FUTURE_PENDING_EXT zurückgeben, wenn future nicht im Status „Bereit“ ist. Die Laufzeit muss XR_ERROR_FUTURE_INVALID_EXT zurückgeben, wenn future bereits abgeschlossen oder abgebrochen wurde.

Gültige Verwendung (implizit)

Rückgabecodes

Erfolg

  • XR_SUCCESS
  • XR_SESSION_LOSS_PENDING

Fehler

  • 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

Die Struktur XrCreateSpatialPersistenceContextCompletionEXT ist so definiert:

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

Mitgliederbeschreibungen

Zukünftige Rückgabecodes

futureResult-Werte:

Erfolg

  • XR_SUCCESS
  • XR_SESSION_LOSS_PENDING

Fehler

  • 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

Wenn sowohl futureResult als auch createResult Erfolgscodes sind, muss persistenceContext gültig sein. Wenn persistenceContext gültig ist, muss es innerhalb des Lebenszyklus von xrCreateSpatialPersistenceContextAsyncEXT :: session oder bis die Anwendung xrDestroySpatialPersistenceContextEXT mit persistenceContext verwendet, gültig bleiben, je nachdem, was zuerst eintritt.

Die Laufzeit muss createResult nur dann festlegen, wenn futureResult ein Erfolgscode ist.

Gültige Verwendung (implizit)

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;

Die Aufzählung XrSpatialPersistenceContextResultEXT gibt die verschiedenen Arten von Ergebniscodes für einen Persistenzvorgang an. Fehler während Persistenzvorgängen liegen nicht immer im Einflussbereich der Anwendung. Diese Aufzählung wird verwendet, um solche Fälle zu vermitteln. Ähnlich wie bei XrResult sind Erfolgscodes in der Aufzählung XrSpatialPersistenceContextResultEXT nicht negative Werte und Fehlercodes negative Werte.

Die Enums haben die folgenden Bedeutungen:

Enum-Beschreibung

XR_SPATIAL_PERSISTENCE_CONTEXT_RESULT_SUCCESS_EXT

Der Persistenzkontextvorgang war erfolgreich.

XR_SPATIAL_PERSISTENCE_CONTEXT_RESULT_ENTITY_NOT_TRACKING_EXT

Der Persistenzvorgang ist fehlgeschlagen, weil die Entität von der Laufzeit nicht verfolgt werden konnte. (Hinzugefügt durch die Erweiterung „XR_EXT_spatial_persistence_operations“)

XR_SPATIAL_PERSISTENCE_CONTEXT_RESULT_PERSIST_UUID_NOT_FOUND_EXT

Die angegebene persistente UUID wurde nicht im Speicher gefunden. (Hinzugefügt durch die Erweiterung „XR_EXT_spatial_persistence_operations“)

XR_SPATIAL_PERSISTENCE_CONTEXT_RESULT_LOCALIZATION_FAILURE_ANDROIDX1

Der Persistenzvorgang ist fehlgeschlagen, weil die Lokalisierung fehlgeschlagen ist. (Hinzugefügt durch die Erweiterung „XR_ANDROIDX1_spatial_anchor_cloud_sharing“)

XR_SPATIAL_PERSISTENCE_CONTEXT_RESULT_MAP_FEATURE_INSUFFICIENT_ANDROIDX1

Der Persistenzvorgang ist fehlgeschlagen, weil das Lokalisierungskarten-Feature nicht ausreicht. (Hinzugefügt durch die Erweiterung „XR_ANDROIDX1_spatial_anchor_cloud_sharing“)

XR_SPATIAL_PERSISTENCE_CONTEXT_RESULT_NETWORK_FAILURE_ANDROIDX1

Der Persistenzvorgang ist fehlgeschlagen, weil die Netzwerkverbindung fehlgeschlagen ist. (Hinzugefügt durch die Erweiterung „XR_ANDROIDX1_spatial_anchor_cloud_sharing“)

XR_SPATIAL_PERSISTENCE_CONTEXT_RESULT_NETWORK_TIMEOUT_ANDROIDX1

Der Persistenzvorgang ist aufgrund einer Netzwerkzeitüberschreitung fehlgeschlagen. (Hinzugefügt durch die Erweiterung „XR_ANDROIDX1_spatial_anchor_cloud_sharing“)

Kontext für räumliche Persistenz löschen

Die Funktion xrDestroySpatialPersistenceContextEXT ist so definiert:

XrResult xrDestroySpatialPersistenceContextEXT(
    XrSpatialPersistenceContextEXT              persistenceContext);

Parameterbeschreibungen

Die Anwendung kann xrDestroySpatialPersistenceContextEXT verwenden, um das persistenceContext-Handle freizugeben, wenn sie mit den Aufgaben zur räumlichen Persistenz fertig ist.

Die Laufzeit darf die zugrunde liegenden Ressourcen für persistenceContext nicht zerstören, wenn xrDestroySpatialPersistenceContextEXT aufgerufen wird, sofern gültige XrSpatialContextEXT-Handles vorhanden sind, mit denen persistenceContext über XrSpatialContextPersistenceConfigEXT verknüpft war. Das liegt daran, dass die Ressourcen des Persistenzkontexts weiterhin vom räumlichen Kontext verwendet werden, um persistente Entitäten zu erkennen. Wenn Sie das Handle des Persistenzkontexts in einer solchen Situation löschen, wird nur der Zugriff der Anwendung auf diese Ressourcen entfernt.

Die Ressourcen für einen zerstörten XrSpatialPersistenceContextEXT müssen freigegeben werden, wenn alle XrSpatialContextEXT-Handles, mit denen der Persistenzkontext verknüpft war, zerstört wurden.

Gültige Verwendung (implizit)

Threadsicherheit

  • Der Zugriff auf persistenceContext und alle untergeordneten Handles muss extern synchronisiert werden.

Rückgabecodes

Erfolg

  • XR_SUCCESS

Fehler

  • XR_ERROR_FUNCTION_UNSUPPORTED
  • XR_ERROR_HANDLE_INVALID
  • XR_ERROR_RUNTIME_FAILURE

Persistente Entitäten entdecken

Persistenzkomponente

Persistente räumliche Entitäten enthalten die Persistenzkomponente, die die Laufzeit in die Erkennungs- und Aktualisierungs-Snapshots aufnehmen muss, wenn XR_SPATIAL_COMPONENT_TYPE_PERSISTENCE_EXT während der Erstellung von XrSpatialContextEXT aktiviert und in XrSpatialDiscoverySnapshotCreateInfoEXT :: componentTypes oder XrSpatialUpdateSnapshotCreateInfoEXT :: componentTypes enthalten ist.

Komponentendaten

Die Struktur XrSpatialPersistenceDataEXT ist so definiert:

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

Mitgliederbeschreibungen

Gültige Verwendung (implizit)

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;

Die Aufzählung XrSpatialPersistenceStateEXT gibt die verschiedenen Status der beibehaltenen UUID an.

Die Enums haben die folgenden Bedeutungen:

Enum-Beschreibung

XR_SPATIAL_PERSISTENCE_STATE_LOADED_EXT

Die persistente UUID wurde aus dem Speicher geladen.

XR_SPATIAL_PERSISTENCE_STATE_NOT_FOUND_EXT

Die persistente UUID wurde nicht im Speicher gefunden und wurde entweder daraus entfernt oder war nie darin.

Komponentenlistenstruktur zum Abfragen von Daten

Die Struktur XrSpatialComponentPersistenceListEXT ist so definiert:

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

Mitgliederbeschreibungen

  • type ist der XrStructureType dieser Struktur.
  • next ist NULL oder ein Zeiger auf die nächste Struktur in einer Strukturkette. Solche Strukturen sind weder in OpenXR noch in dieser Erweiterung definiert.
  • persistDataCount ist ein uint32_t, der die Anzahl der Elemente im Array persistData beschreibt.
  • persistData ist ein Array von XrSpatialPersistenceDataEXT .

Die Laufzeit muss XR_ERROR_VALIDATION_FAILURE von xrQuerySpatialComponentDataEXT zurückgeben, wenn XrSpatialComponentPersistenceListEXT in der nächsten Kette von XrSpatialComponentDataQueryResultEXT :: next enthalten ist, aber XR_SPATIAL_COMPONENT_TYPE_PERSISTENCE_EXT nicht in XrSpatialComponentDataQueryConditionEXT :: componentTypes enthalten ist.

Die Laufzeit muss XR_ERROR_SIZE_INSUFFICIENT von xrQuerySpatialComponentDataEXT zurückgeben, wenn persistDataCount kleiner als XrSpatialComponentDataQueryResultEXT :: entityIdCountOutput ist.

Im Gegensatz zu den anderen Komponenten muss die Laufzeit die Daten für XR_SPATIAL_COMPONENT_TYPE_PERSISTENCE_EXT unabhängig vom XrSpatialEntityTrackingStateEXT festlegen.

Gültige Verwendung (implizit)

Konfiguration

Wenn XR_SPATIAL_COMPONENT_TYPE_PERSISTENCE_EXT in XrSpatialCapabilityComponentTypesEXT :: componentTypes für eine Funktion aufgeführt ist, kann die Anwendung sie aktivieren, indem sie das Enum in die Liste XrSpatialCapabilityConfigurationBaseHeaderEXT :: enabledComponents aufnimmt. Für diese Komponente ist keine spezielle Konfiguration erforderlich, um in die nächste Kette von XrSpatialCapabilityConfigurationBaseHeaderEXT aufgenommen zu werden. Wenn die Anwendung XR_SPATIAL_COMPONENT_TYPE_PERSISTENCE_EXT in der Liste der aktivierten Komponenten enthält, muss sie auch XrSpatialContextPersistenceConfigEXT in der nächsten Kette von XrSpatialContextCreateInfoEXT enthalten. Andernfalls muss die Laufzeit XR_ERROR_SPATIAL_CAPABILITY_CONFIGURATION_INVALID_EXT von xrCreateSpatialContextAsyncEXT zurückgeben.

Räumlichen Kontext mit Persistenzkontexten konfigurieren

Die Struktur XrSpatialContextPersistenceConfigEXT ist so definiert:

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

Mitgliederbeschreibungen

  • type ist der XrStructureType dieser Struktur.
  • next ist NULL oder ein Zeiger auf die nächste Struktur in einer Strukturkette. Solche Strukturen sind weder in OpenXR noch in dieser Erweiterung definiert.
  • persistenceContextCount ist ein uint32_t, der die Anzahl der Elemente im Array persistenceContexts beschreibt.
  • persistenceContexts ist ein Array von XrSpatialPersistenceContextEXT .

Eine Anwendung kann XrSpatialContextPersistenceConfigEXT zur nächsten Kette von XrSpatialContextCreateInfoEXT hinzufügen. Dadurch wird der erstellte XrSpatialContextEXT mit persistenceContexts konfiguriert und die Anwendung kann die räumlichen Entitäten erkennen, die im Speicher beibehalten werden, der durch die XrSpatialPersistenceContextEXT-Handles in persistenceContexts dargestellt wird.

Gültige Verwendung (implizit)

Erkennungs-Snapshot erstellen

Entitäten mit bestimmten UUIDs ermitteln

Die Struktur XrSpatialDiscoveryPersistenceUuidFilterEXT ist so definiert:

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

Mitgliederbeschreibungen

  • type ist der XrStructureType dieser Struktur.
  • next ist NULL oder ein Zeiger auf die nächste Struktur in einer Strukturkette. Solche Strukturen sind weder in OpenXR noch in dieser Erweiterung definiert.
  • persistedUuidCount ist ein uint32_t, der die Anzahl der Elemente im persistedUuids-Array beschreibt.
  • persistedUuids ist ein Array von XrUuid .

Die Anwendung kann XrSpatialDiscoveryPersistenceUuidFilterEXT in der nächsten Kette von XrSpatialDiscoverySnapshotCreateInfoEXT verwenden, um den Erkennungsvorgang auf die Entitäten zu beschränken, deren persistente UUIDs in der Menge der in persistedUuids angegebenen UUIDs enthalten sind.

Wenn die Anwendung XrSpatialDiscoveryPersistenceUuidFilterEXT in der nächsten Kette von XrSpatialDiscoverySnapshotCreateInfoEXT hinzufügt, aber xrCreateSpatialDiscoverySnapshotAsyncEXT :: spatialContext nicht mit einem XrSpatialPersistenceContextEXT über XrSpatialContextPersistenceConfigEXT konfiguriert wurde, muss die Laufzeit XR_ERROR_VALIDATION_FAILURE von xrCreateSpatialDiscoverySnapshotAsyncEXT zurückgeben.

Die Laufzeit muss den Filter XrSpatialDiscoveryPersistenceUuidFilterEXT als „AND“-Bedingung mit allen anderen Filtern behandeln, die in XrSpatialDiscoverySnapshotCreateInfoEXT oder der nächsten Kette angegeben sind. Die Laufzeit muss das Array persistedUuids selbst als „ODER“-Bedingung behandeln, d.h. nach Entitäten filtern, die eine der im Array angegebenen UUIDs haben.

Die Laufzeit muss im erstellten Snapshot einen Eintrag für jede UUID in persistedUuids enthalten, für die sie zu diesem Zeitpunkt den XrSpatialPersistenceStateEXT-Status ermitteln konnte.

  • Wenn die Laufzeit die UUID in ihrem Speicher gefunden hat, dann:

    • Die Laufzeit muss den XrSpatialPersistenceStateEXT in den XrSpatialPersistenceDataEXT dieser Entität auf XR_SPATIAL_PERSISTENCE_STATE_LOADED_EXT setzen.
    • Die Laufzeit muss eine gültige XrSpatialEntityIdEXT für diese Entität im erstellten Snapshot enthalten.
    • Die Laufzeit muss den XrSpatialEntityTrackingStateEXT dieser Entität auf XR_SPATIAL_ENTITY_TRACKING_STATE_TRACKING_EXT setzen, wenn sie die Entität aktiv verfolgt und gültige Daten für ihre Komponenten hat. Andernfalls muss die Laufzeit XrSpatialEntityTrackingStateEXT auf XR_SPATIAL_ENTITY_TRACKING_STATE_PAUSED_EXT setzen.
  • Wenn die Laufzeit festgestellt hat, dass die UUID nicht in ihrem Speicher vorhanden ist (unabhängig davon, ob diese UUID nie im Speicher vorhanden war oder einmal vorhanden war, aber seitdem nicht mehr beibehalten wurde), dann:

  • Wenn die Laufzeit nicht feststellen konnte, ob die UUID in ihrem Speicher vorhanden ist, darf sie nicht in den Snapshot aufgenommen werden.

Die Anwendung kann auch XrSpatialDiscoveryPersistenceUuidFilterEXT in der nächsten Kette von XrSpatialComponentDataQueryConditionEXT verwenden, um Entitäten mit bestimmten UUIDs in vorhandenen Snapshots abzufragen. Wenn XrSpatialDiscoveryPersistenceUuidFilterEXT :: persistedUuids bei Verwendung mit XrSpatialComponentDataQueryConditionEXT eine XrUuid enthält, die nicht in XrSpatialSnapshotEXT enthalten ist, darf die Laufzeit keinen Eintrag für diese XrUuid in das Abfrageergebnis aufnehmen. Außerdem stimmt die Reihenfolge der Entitäten im Abfrageergebnis möglicherweise nicht mit der Reihenfolge der UUIDs in XrSpatialDiscoveryPersistenceUuidFilterEXT :: persistedUuids überein. Die Anwendung sollte XR_SPATIAL_COMPONENT_TYPE_PERSISTENCE_EXT in XrSpatialComponentDataQueryConditionEXT :: componentTypes und XrSpatialComponentPersistenceListEXT in der nächsten Kette von XrSpatialComponentDataQueryResultEXT enthalten und dann XrSpatialPersistenceDataEXT :: persistUuid jedes Abfrageergebnisindex prüfen, um zu ermitteln, welcher UUID der aktuelle Ergebnisindex entspricht.

Gültige Verwendung (implizit)

  • Die Erweiterung XR_EXT_spatial_persistence muss aktiviert sein, bevor XrSpatialDiscoveryPersistenceUuidFilterEXT verwendet werden kann.
  • type muss XR_TYPE_SPATIAL_DISCOVERY_PERSISTENCE_UUID_FILTER_EXT sein
  • next muss NULL oder ein gültiger Zeiger auf die nächste Struktur in einer Strukturkette sein.
  • persistedUuids muss ein Zeiger auf ein Array von persistedUuidCount XrUuid-Strukturen sein.
  • Der Parameter persistedUuidCount muss größer als 0 sein.
Alle persistenten Entitäten erkennen

Wenn die Anwendung xrCreateSpatialDiscoverySnapshotAsyncEXT ohne XrSpatialDiscoveryPersistenceUuidFilterEXT und mit einem XrSpatialContextEXT verwendet, der mit einem XrSpatialPersistenceContextEXT konfiguriert wurde, muss die Laufzeit die Entitäten in den erstellten Snapshot aufnehmen, die im durch XrSpatialPersistenceContextEXT dargestellten Speicher beibehalten werden und die in XrSpatialDiscoverySnapshotCreateInfoEXT bereitgestellten Filter erfüllen. Für diese Entitäten –

  • Die Laufzeit muss den XrSpatialPersistenceStateEXT in den XrSpatialPersistenceDataEXT dieser Entität auf XR_SPATIAL_PERSISTENCE_STATE_LOADED_EXT setzen.
  • Die Laufzeit muss eine gültige XrSpatialEntityIdEXT für diese Entität im erstellten Snapshot enthalten.
  • Die Laufzeit muss den XrSpatialEntityTrackingStateEXT dieser Entität auf XR_SPATIAL_ENTITY_TRACKING_STATE_TRACKING_EXT setzen, wenn sie die Entität aktiv verfolgt und gültige Daten für ihre Komponenten hat. Andernfalls muss die Laufzeit XrSpatialEntityTrackingStateEXT auf XR_SPATIAL_ENTITY_TRACKING_STATE_PAUSED_EXT setzen.

Neue Objekttypen

Neue Befehle

Neue Gebäude

Neue Enums

Neue Enum-Konstanten

  • XR_EXT_SPATIAL_PERSISTENCE_EXTENSION_NAME
  • XR_EXT_spatial_persistence_SPEC_VERSION
  • Erweiterung von XrObjectType :

    • XR_OBJECT_TYPE_SPATIAL_PERSISTENCE_CONTEXT_EXT
  • Erweiterung von XrResult :

    • XR_ERROR_SPATIAL_PERSISTENCE_SCOPE_UNSUPPORTED_EXT
  • Erweiterung von XrSpatialComponentTypeEXT :

    • XR_SPATIAL_COMPONENT_TYPE_PERSISTENCE_EXT
  • Erweiterung von 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

Beispiel-Code

Persistenzkontext erstellen

// 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));

Persistenzkontext mit einem räumlichen Kontext verbinden

// 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));

Alle persistenten Entitäten erkennen

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
  // ...
}

Entitäten mit bestimmten UUIDs ermitteln

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
  // ...
}

Probleme

Versionsverlauf

  • Version 1, 29.08.2024 (Nihav Jain, Google)

    • Anfängliche Beschreibung der Erweiterung