XR_EXT_spatial_persistence

Name String

XR_EXT_spatial_persistence

Tipo de extensión

Extensión de instancia

Número de extensión registrado

764

Revisión

1

Estado de ratificación

Ratified

Dependencias de extensiones y versiones

XR_EXT_spatial_entity
y
XR_EXT_future

Colaboradores

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

Descripción general

Esta extensión permite que las aplicaciones descubran y correlacionen entidades espaciales en sesiones de aplicaciones, sesiones de OpenXR y varios contextos espaciales de OpenXR dentro de una sesión. La extensión XR_EXT_spatial_entity estableció que una entidad dentro de un XrSpatialContextEXT se representa con un XrSpatialEntityIdEXT . Esta extensión amplía ese concepto estableciendo que una entidad, si se conserva, se representa mediante un XrUuid en las sesiones de la aplicación y de OpenXR, es decir, una aplicación puede usar el XrUuid que proporciona esta extensión para identificar una entidad en todas las sesiones. Esta extensión también proporciona superposiciones útiles con la extensión XR_EXT_spatial_entity para descubrir entidades persistentes en el entorno del usuario y la capacidad de consultar los datos de sus componentes.

Contexto de persistencia espacial

Crea un contexto de persistencia espacial

XR_DEFINE_HANDLE(XrSpatialPersistenceContextEXT)

El controlador XrSpatialPersistenceContextEXT representa la conexión a un almacenamiento de entidades espaciales persistente.

La función xrCreateSpatialPersistenceContextAsyncEXT se define de la siguiente manera:

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

Descripciones de los parámetros

  • session es una XrSession en la que estará activo el contexto de persistencia espacial.
  • createInfo es el XrSpatialPersistenceContextCreateInfoEXT que se usa para especificar los parámetros del contexto de persistencia espacial.
  • future es un puntero a un XrFutureEXT .

Una aplicación puede crear un controlador XrSpatialPersistenceContextEXT con la función xrCreateSpatialPersistenceContextAsyncEXT y configurar el alcance del contexto de persistencia en createInfo .

El entorno de ejecución debe devolver XR_ERROR_SPATIAL_PERSISTENCE_SCOPE_UNSUPPORTED_EXT si XrSpatialPersistenceContextCreateInfoEXT :: scope no se enumera con xrEnumerateSpatialPersistenceScopesEXT .

Si un entorno de ejecución aplica un sistema de permisos para controlar el acceso de la aplicación al almacenamiento persistente representado por XrSpatialPersistenceContextEXT , el entorno de ejecución debe devolver XR_ERROR_PERMISSION_INSUFFICIENT si no se otorgaron esos permisos a esta aplicación.

Uso válido (implícito)

Códigos de retorno

Listo

  • XR_SUCCESS
  • XR_SESSION_LOSS_PENDING

Falla

  • 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

La estructura XrSpatialPersistenceContextCreateInfoEXT se define de la siguiente manera:

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

Descripciones de los miembros

  • type es el XrStructureType de esta estructura.
  • next es NULL o un puntero a la siguiente estructura en una cadena de estructuras. No se definen tales estructuras en OpenXR principal ni en esta extensión.
  • scope es un XrSpatialPersistenceScopeEXT que define el alcance de almacenamiento del contexto de persistencia.

La estructura XrSpatialPersistenceContextCreateInfoEXT describe la información para crear un controlador XrSpatialPersistenceContextEXT.

Uso válido (implícito)

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;

La enumeración XrSpatialPersistenceScopeEXT identifica los diferentes tipos de alcances del contexto de persistencia.

Las enumeraciones tienen los siguientes significados:

Descripción de enum

XR_SPATIAL_PERSISTENCE_SCOPE_SYSTEM_MANAGED_EXT

Proporciona a la aplicación acceso de solo lectura (es decir, la aplicación no puede modificar el almacén asociado con este permiso) a las entidades espaciales que el sistema conserva y administra. La aplicación puede usar el UUID en el componente de persistencia para este alcance con el objetivo de correlacionar entidades en contextos espaciales y reinicios del dispositivo.

XR_SPATIAL_PERSISTENCE_SCOPE_LOCAL_ANCHORS_EXT

Las operaciones de persistencia y el acceso a los datos se limitan a las anclas espaciales, en el mismo dispositivo, para el mismo usuario y la misma app (agregado por la extensión XR_EXT_spatial_persistence_operations)

XR_SPATIAL_PERSISTENCE_SCOPE_ANCHORS_FOR_CLOUD_SHARING_ANDROIDX1

Las operaciones de persistencia y el acceso a los datos se limitan a los anclajes espaciales, que son propiedad del mismo proyecto de la nube y se administran en él. (Agregado por la extensión XR_ANDROIDX1_spatial_anchor_cloud_sharing)

La función xrEnumerateSpatialPersistenceScopesEXT se define de la siguiente manera:

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

Descripciones de los parámetros

  • instance es un controlador de un XrInstance .
  • systemId es el XrSystemId cuyos ámbitos de persistencia espacial se enumerarán.
  • persistenceScopeCapacityInput es la capacidad del array persistenceScopes, o 0 para indicar una solicitud de recuperación de la capacidad requerida.
  • persistenceScopeCountOutput es la cantidad de permisos de persistencia o la capacidad requerida en caso de que persistenceScopeCapacityInput sea insuficiente.
  • persistenceScopes es un array de XrSpatialPersistenceScopeEXT . Puede ser NULL si persistenceScopeCapacityInput es 0.
  • Consulta el capítulo Parámetros de tamaño del búfer para obtener una descripción detallada de cómo recuperar el tamaño de persistenceScopes requerido.

La aplicación puede enumerar la lista de permisos de persistencia espacial que admite un XrSystemId determinado con xrEnumerateSpatialPersistenceScopesEXT .

Uso válido (implícito)

  • La extensión XR_EXT_spatial_persistence debe estar habilitada antes de llamar a xrEnumerateSpatialPersistenceScopesEXT.
  • instance debe ser un controlador XrInstance válido.
  • persistenceScopeCountOutput debe ser un puntero a un valor uint32_t
  • Si persistenceScopeCapacityInput no es 0 , persistenceScopes debe ser un puntero a un array de valores persistenceScopeCapacityInput XrSpatialPersistenceScopeEXT

Códigos de retorno

Listo

  • XR_SUCCESS

Falla

  • 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

La función xrCreateSpatialPersistenceContextCompleteEXT se define de la siguiente manera:

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

Descripciones de los parámetros

xrCreateSpatialPersistenceContextCompleteEXT completa la operación asíncrona que inició xrCreateSpatialPersistenceContextAsyncEXT . El entorno de ejecución debe mostrar XR_ERROR_FUTURE_PENDING_EXT si future no está en estado listo. El entorno de ejecución debe devolver XR_ERROR_FUTURE_INVALID_EXT si future ya se completó o canceló.

Uso válido (implícito)

Códigos de retorno

Listo

  • XR_SUCCESS
  • XR_SESSION_LOSS_PENDING

Falla

  • 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

La estructura XrCreateSpatialPersistenceContextCompletionEXT se define de la siguiente manera:

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

Descripciones de los miembros

Códigos de devolución futuros

Valores de futureResult:

Listo

  • XR_SUCCESS
  • XR_SESSION_LOSS_PENDING

Falla

  • 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

Si futureResult y createResult son códigos de éxito, persistenceContext debe ser válido. Si persistenceContext es válido, debe permanecer así dentro del ciclo de vida de xrCreateSpatialPersistenceContextAsyncEXT :: session o hasta que la aplicación use xrDestroySpatialPersistenceContextEXT con persistenceContext , lo que ocurra primero.

El entorno de ejecución debe establecer createResult solo si futureResult es un código de éxito.

Uso válido (implícito)

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;

La enumeración XrSpatialPersistenceContextResultEXT identifica los diferentes tipos de códigos de resultado para una operación de persistencia. Los errores durante las operaciones de persistencia no siempre están bajo el control de la aplicación, y esta enumeración se usa para transmitir esos casos. Al igual que XrResult , los códigos de éxito en la enumeración XrSpatialPersistenceContextResultEXT son valores no negativos, y los códigos de error son valores negativos.

Las enumeraciones tienen los siguientes significados:

Descripción de enum

XR_SPATIAL_PERSISTENCE_CONTEXT_RESULT_SUCCESS_EXT

La operación de contexto de persistencia se realizó correctamente.

XR_SPATIAL_PERSISTENCE_CONTEXT_RESULT_ENTITY_NOT_TRACKING_EXT

La operación de persistencia falló porque el entorno de ejecución no pudo hacer un seguimiento de la entidad. (Agregado por la extensión XR_EXT_spatial_persistence_operations)

XR_SPATIAL_PERSISTENCE_CONTEXT_RESULT_PERSIST_UUID_NOT_FOUND_EXT

No se encontró el UUID de persistencia proporcionado en el almacenamiento. (Agregado por la extensión XR_EXT_spatial_persistence_operations)

XR_SPATIAL_PERSISTENCE_CONTEXT_RESULT_LOCALIZATION_FAILURE_ANDROIDX1

No se pudo completar la operación de persistencia porque falló la localización. (Agregado por la extensión XR_ANDROIDX1_spatial_anchor_cloud_sharing)

XR_SPATIAL_PERSISTENCE_CONTEXT_RESULT_MAP_FEATURE_INSUFFICIENT_ANDROIDX1

La operación de persistencia falló porque la función de mapa de localización es insuficiente. (Agregado por la extensión XR_ANDROIDX1_spatial_anchor_cloud_sharing)

XR_SPATIAL_PERSISTENCE_CONTEXT_RESULT_NETWORK_FAILURE_ANDROIDX1

La operación de persistencia falló porque se produjo un error en la conexión de red. (Agregado por la extensión XR_ANDROIDX1_spatial_anchor_cloud_sharing)

XR_SPATIAL_PERSISTENCE_CONTEXT_RESULT_NETWORK_TIMEOUT_ANDROIDX1

La operación de persistencia falló debido a que se agotó el tiempo de espera de la red. (Agregado por la extensión XR_ANDROIDX1_spatial_anchor_cloud_sharing)

Destruye el contexto de persistencia espacial

La función xrDestroySpatialPersistenceContextEXT se define de la siguiente manera:

XrResult xrDestroySpatialPersistenceContextEXT(
    XrSpatialPersistenceContextEXT              persistenceContext);

Descripciones de los parámetros

La aplicación puede usar xrDestroySpatialPersistenceContextEXT para liberar el controlador persistenceContext cuando termine con las tareas de persistencia espacial.

El entorno de ejecución no debe destruir los recursos subyacentes de persistenceContext cuando se llama a xrDestroySpatialPersistenceContextEXT si hay controladores XrSpatialContextEXT válidos a los que se vinculó persistenceContext a través de XrSpatialContextPersistenceConfigEXT . Esto se debe a que el contexto espacial aún usa los recursos del contexto de persistencia para descubrir entidades persistentes. En tal situación, destruir el controlador del contexto de persistencia solo quita el acceso de la aplicación a estos recursos.

Los recursos de un XrSpatialPersistenceContextEXT destruido deben liberarse cuando se destruyan todos los controladores XrSpatialContextEXT a los que estaba vinculado el contexto de persistencia.

Uso válido (implícito)

Seguridad de subprocesos

  • El acceso a persistenceContext y a cualquier controlador secundario debe sincronizarse de forma externa.

Códigos de retorno

Listo

  • XR_SUCCESS

Falla

  • XR_ERROR_FUNCTION_UNSUPPORTED
  • XR_ERROR_HANDLE_INVALID
  • XR_ERROR_RUNTIME_FAILURE

Descubre entidades persistentes

Componente de persistencia

Las entidades espaciales persistentes tienen el componente de persistencia que el entorno de ejecución debe incluir en las instantáneas de descubrimiento y actualización si XR_SPATIAL_COMPONENT_TYPE_PERSISTENCE_EXT está habilitado durante la creación de XrSpatialContextEXT y se incluye en XrSpatialDiscoverySnapshotCreateInfoEXT :: componentTypes o XrSpatialUpdateSnapshotCreateInfoEXT :: componentTypes .

Datos de componentes

La estructura XrSpatialPersistenceDataEXT se define de la siguiente manera:

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

Descripciones de los miembros

Uso válido (implícito)

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;

La enumeración XrSpatialPersistenceStateEXT identifica los diferentes estados del UUID persistente.

Las enumeraciones tienen los siguientes significados:

Descripción de enum

XR_SPATIAL_PERSISTENCE_STATE_LOADED_EXT

El UUID persistente se cargó correctamente desde el almacenamiento.

XR_SPATIAL_PERSISTENCE_STATE_NOT_FOUND_EXT

No se encontró el UUID persistente en el almacenamiento, ya que se quitó de él o nunca estuvo allí.

Estructura de la lista de componentes para consultar datos

La estructura XrSpatialComponentPersistenceListEXT se define de la siguiente manera:

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

Descripciones de los miembros

  • type es el XrStructureType de esta estructura.
  • next es NULL o un puntero a la siguiente estructura en una cadena de estructuras. No se definen tales estructuras en OpenXR principal ni en esta extensión.
  • persistDataCount es un uint32_t que describe el recuento de elementos en el array persistData.
  • persistData es un array de XrSpatialPersistenceDataEXT .

El entorno de ejecución debe devolver XR_ERROR_VALIDATION_FAILURE de xrQuerySpatialComponentDataEXT si XrSpatialComponentPersistenceListEXT está en la siguiente cadena de XrSpatialComponentDataQueryResultEXT :: next, pero XR_SPATIAL_COMPONENT_TYPE_PERSISTENCE_EXT no se incluye en XrSpatialComponentDataQueryConditionEXT :: componentTypes .

El entorno de ejecución debe devolver XR_ERROR_SIZE_INSUFFICIENT de xrQuerySpatialComponentDataEXT si persistDataCount es menor que XrSpatialComponentDataQueryResultEXT :: entityIdCountOutput .

A diferencia de los otros componentes, el entorno de ejecución debe establecer los datos para XR_SPATIAL_COMPONENT_TYPE_PERSISTENCE_EXT, independientemente de XrSpatialEntityTrackingStateEXT .

Uso válido (implícito)

Configuración

Si XR_SPATIAL_COMPONENT_TYPE_PERSISTENCE_EXT se enumera en XrSpatialCapabilityComponentTypesEXT :: componentTypes para alguna función, la aplicación puede habilitarla incluyendo la enumeración en la lista XrSpatialCapabilityConfigurationBaseHeaderEXT :: enabledComponents. Este componente no requiere ninguna configuración especial para incluirse en la siguiente cadena de XrSpatialCapabilityConfigurationBaseHeaderEXT . Si la aplicación incluye XR_SPATIAL_COMPONENT_TYPE_PERSISTENCE_EXT en la lista de componentes habilitados, debe incluir también XrSpatialContextPersistenceConfigEXT en la siguiente cadena de XrSpatialContextCreateInfoEXT; de lo contrario, el entorno de ejecución debe devolver XR_ERROR_SPATIAL_CAPABILITY_CONFIGURATION_INVALID_EXT desde xrCreateSpatialContextAsyncEXT .

Configura el contexto espacial con contextos de persistencia

La estructura XrSpatialContextPersistenceConfigEXT se define de la siguiente manera:

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

Descripciones de los miembros

  • type es el XrStructureType de esta estructura.
  • next es NULL o un puntero a la siguiente estructura en una cadena de estructuras. No se definen tales estructuras en OpenXR principal ni en esta extensión.
  • persistenceContextCount es un uint32_t que describe el recuento de elementos en el array persistenceContexts.
  • persistenceContexts es un array de XrSpatialPersistenceContextEXT .

Una aplicación puede agregar XrSpatialContextPersistenceConfigEXT a la siguiente cadena de XrSpatialContextCreateInfoEXT . Esto configurará el XrSpatialContextEXT creado con persistenceContexts y permitirá que la aplicación descubra las entidades espaciales que se conservan en el almacenamiento representado por los controladores XrSpatialPersistenceContextEXT en persistenceContexts .

Uso válido (implícito)

Crea una instantánea de descubrimiento

Descubre entidades con UUID específicos

La estructura XrSpatialDiscoveryPersistenceUuidFilterEXT se define de la siguiente manera:

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

Descripciones de los miembros

  • type es el XrStructureType de esta estructura.
  • next es NULL o un puntero a la siguiente estructura en una cadena de estructuras. No se definen tales estructuras en OpenXR principal ni en esta extensión.
  • persistedUuidCount es un uint32_t que describe el recuento de elementos en el array persistedUuids
  • persistedUuids es un array de XrUuid .

La aplicación puede usar XrSpatialDiscoveryPersistenceUuidFilterEXT en la siguiente cadena de XrSpatialDiscoverySnapshotCreateInfoEXT para limitar la operación de descubrimiento solo a las entidades cuyos UUID persistentes estén en el conjunto de UUID proporcionados en persistedUuids .

Si la aplicación agrega XrSpatialDiscoveryPersistenceUuidFilterEXT en la siguiente cadena de XrSpatialDiscoverySnapshotCreateInfoEXT, pero xrCreateSpatialDiscoverySnapshotAsyncEXT :: spatialContext no se configuró con ningún XrSpatialPersistenceContextEXT usando XrSpatialContextPersistenceConfigEXT, el entorno de ejecución debe devolver XR_ERROR_VALIDATION_FAILURE de xrCreateSpatialDiscoverySnapshotAsyncEXT .

El entorno de ejecución debe tratar el filtro XrSpatialDiscoveryPersistenceUuidFilterEXT como una condición "Y" con cualquier otro filtro proporcionado en XrSpatialDiscoverySnapshotCreateInfoEXT o su siguiente cadena. El entorno de ejecución debe tratar el array persistedUuids como una condición "OR", es decir, filtrar las entidades que tienen cualquiera de los UUID proporcionados en ese array.

El entorno de ejecución debe incluir una entrada en la instantánea creada para cada uno de los UUID en persistedUuids para los que pudo determinar el estado XrSpatialPersistenceStateEXT en este momento.

  • Si el entorno de ejecución encontró correctamente el UUID en su almacenamiento, entonces,

    • El entorno de ejecución debe establecer el XrSpatialPersistenceStateEXT en el XrSpatialPersistenceDataEXT de esta entidad en XR_SPATIAL_PERSISTENCE_STATE_LOADED_EXT .
    • El entorno de ejecución debe incluir un XrSpatialEntityIdEXT válido para esta entidad en la instantánea creada.
    • El entorno de ejecución debe establecer el XrSpatialEntityTrackingStateEXT de esa entidad en XR_SPATIAL_ENTITY_TRACKING_STATE_TRACKING_EXT si realiza un seguimiento activo de la entidad y tiene datos válidos para sus componentes. De lo contrario, el entorno de ejecución debe establecer XrSpatialEntityTrackingStateEXT en XR_SPATIAL_ENTITY_TRACKING_STATE_PAUSED_EXT .
  • Si el entorno de ejecución determinó que el UUID no está presente en su almacenamiento (independientemente de si ese UUID nunca estuvo en el almacenamiento o estuvo presente una vez, pero desde entonces no se conservó), entonces, ocurrirá lo siguiente:

    • El entorno de ejecución debe establecer el XrSpatialPersistenceStateEXT en el XrSpatialPersistenceDataEXT de esta entidad en XR_SPATIAL_PERSISTENCE_STATE_NOT_FOUND_EXT para indicarle a la aplicación que este UUID ya no está presente en el almacenamiento.
    • El entorno de ejecución debe establecer el XrSpatialEntityIdEXT de esta entidad en la instantánea creada en XR_NULL_SPATIAL_ENTITY_ID_EXT .
    • El entorno de ejecución debe establecer el XrSpatialEntityTrackingStateEXT de esa entidad en XR_SPATIAL_ENTITY_TRACKING_STATE_STOPPED_EXT para indicarle a la aplicación que nunca se realizará un seguimiento de esta entidad.
  • Si el entorno de ejecución no pudo determinar si el UUID está presente en su almacenamiento o no, no debe incluirlo en la instantánea.

La aplicación también puede usar XrSpatialDiscoveryPersistenceUuidFilterEXT en la siguiente cadena de XrSpatialComponentDataQueryConditionEXT para consultar entidades de UUID específicos en instantáneas existentes. Cuando se usa con XrSpatialComponentDataQueryConditionEXT , si XrSpatialDiscoveryPersistenceUuidFilterEXT :: persistedUuids contiene algún XrUuid que no esté en XrSpatialSnapshotEXT , el entorno de ejecución no debe incluir una entrada para ese XrUuid en el resultado de la consulta. Además, el orden (secuencia) de las entidades en el resultado de la consulta puede no coincidir con el orden de los UUID proporcionados en XrSpatialDiscoveryPersistenceUuidFilterEXT :: persistedUuids . La aplicación debe incluir XR_SPATIAL_COMPONENT_TYPE_PERSISTENCE_EXT en XrSpatialComponentDataQueryConditionEXT :: componentTypes y XrSpatialComponentPersistenceListEXT en la siguiente cadena de XrSpatialComponentDataQueryResultEXT y, luego, verificar el XrSpatialPersistenceDataEXT :: persistUuid de cada índice de resultados de la consulta para comprender a qué UUID corresponde el índice de resultados actual.

Uso válido (implícito)

Descubre todas las entidades persistentes

Si la aplicación usa xrCreateSpatialDiscoverySnapshotAsyncEXT sin XrSpatialDiscoveryPersistenceUuidFilterEXT y con un XrSpatialContextEXT que se configuró con un XrSpatialPersistenceContextEXT , el entorno de ejecución debe incluir esas entidades en la instantánea creada que se conservan en el almacenamiento representado por XrSpatialPersistenceContextEXT y cumplen con los filtros proporcionados en XrSpatialDiscoverySnapshotCreateInfoEXT . Para esas entidades,

  • El entorno de ejecución debe establecer el XrSpatialPersistenceStateEXT en el XrSpatialPersistenceDataEXT de esta entidad en XR_SPATIAL_PERSISTENCE_STATE_LOADED_EXT .
  • El entorno de ejecución debe incluir un XrSpatialEntityIdEXT válido para esta entidad en la instantánea creada.
  • El entorno de ejecución debe establecer el XrSpatialEntityTrackingStateEXT de esa entidad en XR_SPATIAL_ENTITY_TRACKING_STATE_TRACKING_EXT si realiza un seguimiento activo de la entidad y tiene datos válidos para sus componentes. De lo contrario, el entorno de ejecución debe establecer XrSpatialEntityTrackingStateEXT en XR_SPATIAL_ENTITY_TRACKING_STATE_PAUSED_EXT .

Nuevos tipos de objetos

Comandos nuevos

Estructuras nuevas

Enums nuevas

Nuevas constantes de enum

  • XR_EXT_SPATIAL_PERSISTENCE_EXTENSION_NAME
  • XR_EXT_spatial_persistence_SPEC_VERSION
  • Extiende XrObjectType :

    • XR_OBJECT_TYPE_SPATIAL_PERSISTENCE_CONTEXT_EXT
  • Extiende XrResult :

    • XR_ERROR_SPATIAL_PERSISTENCE_SCOPE_UNSUPPORTED_EXT
  • Extiende XrSpatialComponentTypeEXT :

    • XR_SPATIAL_COMPONENT_TYPE_PERSISTENCE_EXT
  • Extiende 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

Código de ejemplo

Crea un contexto de persistencia

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

Cómo conectar el contexto de persistencia a un contexto espacial

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

Descubre todas las entidades persistentes

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

Descubre entidades con UUID específicos

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

Problemas

Historial de versiones

  • Revisión 1, 29 de agosto de 2024 (Nihav Jain, Google)

    • Descripción inicial de la extensión