XR_EXT_spatial_anchor

Name String

XR_EXT_spatial_anchor

Tipo de extensión

Extensión de instancia

Número de extensión registrado

763

Revisión

1

Estado de ratificación

Ratified

Dependencias de extensiones y versiones

XR_EXT_spatial_entity

Colaboradores

Nihav Jain, 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 se basa en XR_EXT_spatial_entity y permite que las aplicaciones creen anclajes espaciales, que son puntos arbitrarios en el entorno físico del usuario que, luego, el entorno de ejecución rastreará. Luego, el entorno de ejecución debería ajustar la posición y la orientación del origen del ancla con el tiempo según sea necesario, independientemente de todos los demás espacios y anclas, para garantizar que mantenga su asignación original al mundo real.

Un ancla que hace un seguimiento de una posición y orientación dadas dentro de un XrSpatialContextEXT se representa como una entidad espacial con (o "que tiene") el componente XR_SPATIAL_COMPONENT_TYPE_ANCHOR_EXT.

Beneficio de usar anclas

A medida que la comprensión del entorno físico del usuario por parte del entorno de ejecución se actualiza durante el ciclo de vida de un XrSpatialContextEXT , los objetos virtuales pueden parecer alejarse del lugar donde los colocó la aplicación, lo que afecta el realismo de la aplicación y la calidad de la experiencia del usuario. Si se crea un ancla cerca de donde se coloca un objeto virtual y, luego, siempre se renderiza ese objeto virtual en relación con su ancla, una aplicación puede garantizar que cada objeto virtual parezca permanecer en la misma posición y orientación en el entorno físico. Además, a diferencia de ciertos espacios de referencia, las anclas no se ven afectadas por el recentrado a nivel del sistema.

Asistencia del entorno de ejecución

Si el entorno de ejecución admite anclajes espaciales, debe indicarlo enumerando XR_SPATIAL_CAPABILITY_ANCHOR_EXT en xrEnumerateSpatialCapabilitiesEXT .

Configuración

La estructura XrSpatialCapabilityConfigurationAnchorEXT se define de la siguiente manera:

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

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.
  • capability es un XrSpatialCapabilityEXT .
  • enabledComponentCount es un uint32_t que describe el recuento de elementos en el array enabledComponents.
  • enabledComponents es un puntero a un array de XrSpatialComponentTypeEXT .

Las aplicaciones pueden habilitar la capacidad espacial XR_SPATIAL_CAPABILITY_ANCHOR_EXT incluyendo un puntero a una estructura XrSpatialCapabilityConfigurationAnchorEXT en XrSpatialContextCreateInfoEXT :: capabilityConfigs .

El entorno de ejecución debe devolver XR_ERROR_VALIDATION_FAILURE si capability no es XR_SPATIAL_CAPABILITY_ANCHOR_EXT .

Uso válido (implícito)

Componentes garantizados

Un entorno de ejecución que admita XR_SPATIAL_CAPABILITY_ANCHOR_EXT debe proporcionar los siguientes componentes espaciales como componentes garantizados de todas las entidades creadas o descubiertas por esta capacidad, y debe enumerarlos en xrEnumerateSpatialCapabilityComponentTypesEXT :

  • XR_SPATIAL_COMPONENT_TYPE_ANCHOR_EXT

Componente de anclaje

Datos de componentes

XR_SPATIAL_COMPONENT_TYPE_ANCHOR_EXT usa XrPosef para sus datos, lo que proporciona la posición y la orientación del ancla.

Estructura de lista de componentes para consultar datos

La estructura XrSpatialComponentAnchorListEXT se define de la siguiente manera:

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

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.
  • locationCount es un uint32_t que describe el recuento de elementos en el array locations.
  • locations es un array de XrPosef .

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

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

Uso válido (implícito)

Configuración

Si XR_SPATIAL_COMPONENT_TYPE_ANCHOR_EXT se enumera en XrSpatialCapabilityComponentTypesEXT :: componentTypes para alguna capacidad, una aplicación puede habilitarla incluyendo el enumerante en la lista XrSpatialCapabilityConfigurationBaseHeaderEXT :: enabledComponents de la estructura derivada XrSpatialCapabilityConfigurationBaseHeaderEXT de la capacidad que admite este componente.

Este componente no requiere ninguna configuración especial para incluirse en la cadena XrSpatialCapabilityConfigurationBaseHeaderEXT :: next.

Crea un ancla espacial

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

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

Descripciones de los parámetros

La aplicación puede crear un ancla espacial con xrCreateSpatialAnchorEXT .

Para obtener datos de componentes actualizados de un ancla, pasa el valor propagado en anchorEntity a XrSpatialUpdateSnapshotCreateInfoEXT :: entities cuando crees una instantánea. La aplicación puede usar anchorEntityId para identificar de forma única este ancla en el array XrSpatialComponentDataQueryResultEXT :: entityIds cuando se usa xrQuerySpatialComponentDataEXT .

El entorno de ejecución debe devolver XR_ERROR_VALIDATION_FAILURE de xrCreateSpatialAnchorEXT si no se configuró XR_SPATIAL_CAPABILITY_ANCHOR_EXT para spatialContext . Consulta Configuración para saber cómo configurar un XrSpatialContextEXT para la función XR_SPATIAL_CAPABILITY_ANCHOR_EXT.

El ancla representada por anchorEntity solo es válida durante el ciclo de vida de spatialContext o hasta que la aplicación llame a xrDestroySpatialEntityEXT en ella, lo que ocurra primero. Otras extensiones pueden ofrecer funciones para conservar este ancla recién creada en varias XrSession o para compartirla entre límites de procesos con otras aplicaciones.

Un ancla recién creada, hasta que se destruya, debe ser detectable en su contexto espacial superior. Esto significa que el entorno de ejecución debe incluir anchorEntityId en la instantánea creada con xrCreateSpatialDiscoverySnapshotAsyncEXT para spatialContext si el ancla coincide con los criterios de descubrimiento establecidos en XrSpatialDiscoverySnapshotCreateInfoEXT . El ancla recién creada también puede detectarse en otros contextos espaciales configurados con XR_SPATIAL_CAPABILITY_ANCHOR_EXT, aunque con un XrSpatialEntityIdEXT diferente, ya que un XrSpatialEntityIdEXT en particular es único para su XrSpatialContextEXT .

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_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 (si XR_ANDROID_spatial_entity_bound_anchor está habilitado)
  • XR_ERROR_SPATIAL_ENTITY_ID_INVALID_EXT (si XR_ANDROID_spatial_entity_bound_anchor está habilitado)

La estructura XrSpatialAnchorCreateInfoEXT se define de la siguiente manera:

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

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.
  • baseSpace es el XrSpace en el que se aplica pose.
  • time es el XrTime en el que se encuentra baseSpace (y se aplica pose).
  • pose es la ubicación de la entidad de anclaje.

Uso válido (implícito)

Consulta la pose de un ancla

Después de crear el ancla, el entorno de ejecución debería ajustar su posición y orientación con el tiempo en relación con otros espacios para mantener la mejor alineación posible con su ubicación original en el mundo real, incluso si eso cambia la relación del ancla con el XrSpatialAnchorCreateInfoEXT :: baseSpace original que se usó para inicializarla.

La aplicación puede usar xrCreateSpatialUpdateSnapshotEXT con el XrSpatialEntityEXT del ancla para crear un nuevo XrSpatialSnapshotEXT y, luego, consultar el componente XR_SPATIAL_COMPONENT_TYPE_ANCHOR_EXT de esa instantánea con xrQuerySpatialComponentDataEXT . La aplicación puede agregar XrSpatialComponentAnchorListEXT a XrSpatialComponentDataQueryResultEXT :: next para recuperar los datos de ubicación más recientes de los anclajes.

El entorno de ejecución puede establecer el estado de seguimiento de un ancla recién creada en XR_SPATIAL_ENTITY_TRACKING_STATE_PAUSED_EXT . La aplicación debe leer solo el estado de la entidad de anclaje proporcionado en XrSpatialComponentDataQueryResultEXT :: entityStates y los datos del componente de anclaje de la entidad si el estado de seguimiento es XR_SPATIAL_ENTITY_TRACKING_STATE_TRACKING_EXT .

Lineamientos para usar anclas

  • La pose de cada ancla se ajusta de forma independiente de cualquier otra ancla o espacio. Los objetos virtuales anclados por separado pueden desplazarse o rotar entre sí, lo que rompe la jerarquía espacial en los casos en que se espera que estos objetos virtuales permanezcan en su lugar entre sí. En esos casos, la aplicación debería reutilizar el mismo ancla para todos los objetos virtuales que no se mueven entre sí.
  • La aplicación debe destruir cualquier controlador XrSpatialEntityEXT para los anclajes que ya no se usen con el fin de liberar los recursos que el entorno de ejecución pueda estar usando para hacer un seguimiento de esos anclajes.

Código de ejemplo

Configura la capacidad de anclaje

En el siguiente ejemplo, se muestra cómo configurar la capacidad de anclaje cuando se crea un contexto espacial.

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

Crea un anclaje espacial y obtén su ubicación

En el siguiente ejemplo, se muestra cómo crear un ancla espacial y obtener su pose en cada fotograma.

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

Comandos nuevos

Estructuras nuevas

Nuevas constantes de enum

  • XR_EXT_SPATIAL_ANCHOR_EXTENSION_NAME
  • XR_EXT_spatial_anchor_SPEC_VERSION
  • Extiende XrSpatialCapabilityEXT :

    • XR_SPATIAL_CAPABILITY_ANCHOR_EXT
  • Extiende XrSpatialComponentTypeEXT :

    • XR_SPATIAL_COMPONENT_TYPE_ANCHOR_EXT
  • Extiende XrStructureType :

    • XR_TYPE_SPATIAL_ANCHOR_CREATE_INFO_EXT
    • XR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_ANCHOR_EXT
    • XR_TYPE_SPATIAL_COMPONENT_ANCHOR_LIST_EXT

Problemas

Historial de versiones

  • Revisión 1, 10 de julio de 2024 (Nihav Jain, Google)

    • Descripción inicial de la extensión