XR_ANDROID_spatial_component_subsumed_by

Cadena de nombre

XR_ANDROID_spatial_component_subsumed_by

Tipo de extensión

Extensión de la instancia

Número de extensión registrado

792

Revisión

1

Estado de ratificación

No se ratificó

Dependencias de extensiones y versiones

XR_EXT_spatial_entity
y
XR_EXT_spatial_plane_tracking

Fecha de la última modificación

19/8/2025

Estado de la IP

No hay reclamos conocidos por IP.

Colaboradores

Brian Chen, Google
Kyle Chen, Google
Levana Chen, Google
Nihav Jain, Google
Spencer Quin, Google

Descripción general

Esta extensión se basa en XR_EXT_spatial_entity y proporciona un nuevo componente para XR_SPATIAL_CAPABILITY_PLANE_TRACKING_EXT , para exponer la propiedad subsumed_by.

Cuando el tiempo de ejecución haya adquirido suficiente información del entorno para detectar que 2 planos rastreados son en realidad el mismo, el componente subsumed_by con el ID de uno de los planos se adjuntará al otro.

Esta extensión también introduce un nuevo filtro, que la aplicación puede encadenar a XrSpatialDiscoverySnapshotCreateInfoEXT para filtrar cualquier entidad que tenga el componente subsumed_by adjunto.

Permisos

Las aplicaciones para Android deben tener el permiso android.permission.SCENE_UNDERSTANDING_COARSE incluido en su manifiesto, ya que esta extensión hace un seguimiento de los planos en el entorno. El permiso android.permission.SCENE_UNDERSTANDING_COARSE se considera un permiso peligroso.

(nivel de protección: peligroso)

Asistencia del entorno de ejecución

Si el tiempo de ejecución admite subumed_by, debe admitir la capacidad de seguimiento de planos y, para indicarlo, debe enumerar XR_SPATIAL_CAPABILITY_PLANE_TRACKING_EXT en xrEnumerateSpatialCapabilitiesEXT .

Si el tiempo de ejecución proporciona subsumed_by, debe indicarlo enumerando XR_SPATIAL_COMPONENT_TYPE_SUBSUMED_BY_ANDROID como un componente compatible para la capacidad XR_SPATIAL_CAPABILITY_PLANE_TRACKING_EXT en xrEnumerateSpatialCapabilityComponentTypesEXT .

Todos los datos de los componentes de la entidad XR_SPATIAL_COMPONENT_TYPE_SUBSUMED_BY_ANDROID adjunta deben ser idénticos a los de la entidad que la subsume.

Subsumed By Component

Datos del componente

XR_SPATIAL_COMPONENT_TYPE_SUBSUMED_BY_ANDROID usa la estructura XrSpatialEntityIdEXT para sus datos, que representa el ID de la entidad que subsume.

Struct de lista de componentes para consultar datos

La estructura XrSpatialComponentSubsumedByListANDROID se define de la siguiente manera:

typedef struct XrSpatialComponentSubsumedByListANDROID {
    XrStructureType          type;
    void*                    next;
    uint32_t                 subsumedUniqueIdCount;
    XrSpatialEntityIdEXT*    subsumedUniqueIds;
} XrSpatialComponentSubsumedByListANDROID;

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.
  • subsumedUniqueIdCount es un uint32_t que describe el recuento de elementos en el array subsumedUniqueIds.
  • subsumedUniqueIds es un array de XrSpatialEntityIdEXT .

La aplicación puede consultar el componente subsumed_by de las entidades espaciales en un XrSpatialSnapshotEXT agregando XR_TYPE_SPATIAL_COMPONENT_SUBSUMED_BY_LIST_ANDROID a la siguiente cadena de XrSpatialComponentDataQueryResultEXT .

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

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

Uso válido (implícito)

  • La extensión XR_ANDROID_spatial_component_subsumed_by debe habilitarse antes de usar XrSpatialComponentSubsumedByListANDROID
  • type debe ser XR_TYPE_SPATIAL_COMPONENT_SUBSUMED_BY_LIST_ANDROID
  • next debe ser NULL o un puntero válido a la siguiente estructura en una cadena de estructuras
  • subsumedUniqueIds debe ser un puntero a un array de valores subsumedUniqueIdCount XrSpatialEntityIdEXT.
  • El parámetro subsumedUniqueIdCount debe ser mayor que 0.

Configuración

Si XR_SPATIAL_COMPONENT_TYPE_SUBSUMED_BY_ANDROID se enumera en XrSpatialCapabilityComponentTypesEXT :: componentTypes para la capacidad XR_SPATIAL_CAPABILITY_PLANE_TRACKING_EXT, la aplicación puede habilitarla incluyendo la enumeración en la lista XrSpatialCapabilityConfigurationBaseHeaderEXT :: enabledComponents de la estructura derivada XrSpatialCapabilityConfigurationBaseHeaderEXT de la capacidad que admite este componente.

Filtra las entidades subsumidas

La estructura XrSpatialDiscoveryUniqueEntitiesFilterANDROID se define de la siguiente manera:

typedef struct XrSpatialDiscoveryUniqueEntitiesFilterANDROID {
    XrStructureType    type;
    const void*        next;
} XrSpatialDiscoveryUniqueEntitiesFilterANDROID;

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.

La aplicación puede incluir XrSpatialDiscoveryUniqueEntitiesFilterANDROID en la siguiente cadena de XrSpatialDiscoverySnapshotCreateInfoEXT para obtener una instantánea con entidades que no están subsumidas por otra entidad.

Si las aplicaciones encadenan XrSpatialDiscoveryUniqueEntitiesFilterANDROID a XrSpatialDiscoverySnapshotCreateInfoEXT mientras incluyen el componente XR_SPATIAL_COMPONENT_TYPE_SUBSUMED_BY_ANDROID en XrSpatialDiscoverySnapshotCreateInfoEXT :: componentTypes , el tiempo de ejecución debe devolver XR_ERROR_VALIDATION_FAILURE .

Si XrSpatialDiscoveryUniqueEntitiesFilterANDROID encadena XrSpatialDiscoverySnapshotCreateInfoEXT, pero no incluye ningún componente en XrSpatialDiscoverySnapshotCreateInfoEXT :: componentTypes, el tiempo de ejecución debe incluir todas las entidades espaciales en la instantánea que tengan el conjunto de componentes enumerados en XrSpatialCapabilityConfigurationBaseHeaderEXT :: enabledComponents para las capacidades configuradas para spatialContext, excepto las entidades que tengan el componente XR_SPATIAL_COMPONENT_TYPE_SUBSUMED_BY_ANDROID.

Uso válido (implícito)

Ejemplo de código

Configura la capacidad de seguimiento de planos

En el siguiente código de ejemplo, se muestra cómo crear un contexto espacial con capacidad de XR_SPATIAL_CAPABILITY_PLANE_TRACKING_EXT que admita subsumed_by.

// Check runtime supported capabilities
uint32_t capabilityCount;
CHK_XR(xrEnumerateSpatialCapabilitiesEXT(instance, systemId, 0, &capabilityCount, nullptr));
std::vector<XrSpatialCapabilityEXT> capabilities(capabilityCount);
CHK_XR(xrEnumerateSpatialCapabilitiesEXT(instance, systemId, capabilityCount, &capabilityCount, capabilities.data()));

if (std::find(capabilities.begin(), capabilities.end(), XR_SPATIAL_CAPABILITY_PLANE_TRACKING_EXT) == capabilities.end()) {
  return;
}

std::vector<XrSpatialComponentTypeEXT> planeTrackingComponents {
  XR_SPATIAL_COMPONENT_TYPE_BOUNDED_2D_EXT,
  XR_SPATIAL_COMPONENT_TYPE_PLANE_ALIGNMENT_EXT,
  XR_SPATIAL_COMPONENT_TYPE_SUBSUMED_BY_ANDROID,
};

// Create capability config for plane tracking
XrSpatialCapabilityConfigurationPlaneTrackingEXT planeTrackingConfig {
  .type = XR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_PLANE_TRACKING_EXT,
  .next = nullptr,
  .capability = XR_SPATIAL_CAPABILITY_PLANE_TRACKING_EXT,
  .enabledComponentCount = (uint32_t)planeTrackingComponents.size(),
  .enabledComponents = planeTrackingComponents.data(),
};

// Create spatial context
std::vector<const XrSpatialCapabilityConfigurationBaseHeaderEXT*> capabilityConfigs;
capabilityConfigs.push_back(reinterpret_cast<const XrSpatialCapabilityConfigurationBaseHeaderEXT*>(&planeTrackingConfig));

XrSpatialContextCreateInfoEXT contextCreateInfo{
  .type = XR_TYPE_SPATIAL_CONTEXT_CREATE_INFO_EXT,
  .next = nullptr,
  .capabilityConfigCount = (uint32_t)capabilityConfigs.size(),
  .capabilityConfigs = capabilityConfigs.data(),
};

CHK_XR(xrCreateSpatialContextAsyncEXT(session, &contextCreateInfo, &future))

// Completes creating spatial context
XrCreateSpatialContextCompletionEXT contextCompletion{
XR_TYPE_CREATE_SPATIAL_CONTEXT_COMPLETION_EXT};

CHK_XR(xrCreateSpatialContextCompleteEXT(session, future, &contextCompletion))

Consulta datos de componentes

En el siguiente ejemplo de código, se muestra cómo consultar los datos del componente subsumed_by desde un contexto configurado con XR_SPATIAL_CAPABILITY_PLANE_TRACKING_EXT .

// Create Discovery Snapshot
XrSpatialDiscoverySnapshotCreateInfoEXT discoverySnapshotCreateInfo {
  .type = XR_TYPE_SPATIAL_DISCOVERY_SNAPSHOT_CREATE_INFO_EXT,
};

CHK_XR(xrCreateSpatialDiscoverySnapshotAsyncEXT (
spatialContext, &discoverySnapshotCreateInfo, &future));

// Poll the state till snapshot it's ready.
waitUntilReady(future);

// Complete async operation.
XrCreateSpatialDiscoverySnapshotCompletionInfoEXT
  createSnapshotCompletionInfo {
    .type   = XR_TYPE_CREATE_SPATIAL_DISCOVERY_SNAPSHOT_COMPLETION_INFO_EXT,
    .baseSpace = space,
    .time      = updateTime,
    .future    = future,
  };

XrCreateSpatialDiscoverySnapshotCompletionEXT completion {
  XR_TYPE_CREATE_SPATIAL_DISCOVERY_SNAPSHOT_COMPLETION_EXT};

CHK_XR(xrCreateSpatialDiscoverySnapshotCompleteEXT(
           spatialContext, &createSnapshotCompletionInfo,
           &completion));

if(completion.futureResult != XR_SUCCESS) return;

// Query subsumed_by components
std::array<XrSpatialComponentTypeEXT, 1> enabledComponents = {
  XR_SPATIAL_COMPONENT_TYPE_SUBSUMED_BY_ANDROID
};

XrSpatialComponentDataQueryConditionEXT queryCond {
  .type = XR_TYPE_SPATIAL_COMPONENT_DATA_QUERY_CONDITION_EXT,
  .componentTypeCount = 1,
  .componentTypes     = enabledComponents.data(),
};

XrSpatialComponentDataQueryResultEXT queryResult {
  .type = XR_TYPE_SPATIAL_COMPONENT_DATA_QUERY_RESULT_EXT,
};

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

// Query again with allocated memory
std::vector<XrSpatialEntityIdEXT> subsumedUniqueIds;
subsumedUniqueIds.resize(queryResult.entityIdCountOutput);
XrSpatialComponentSubsumedByListANDROID subsumedByList {
  .type = XR_TYPE_SPATIAL_COMPONENT_SUBSUMED_BY_LIST_ANDROID,
  .subsumedUniqueIdCount = static_cast<uint32_t>(subsumedUniqueIds.size()),
  .subsumedUniqueIds = subsumedUniqueIds.data(),
};

queryResult.next = &subsumedByList;
CHK_XR(xrQuerySpatialComponentDataEXT(
           completion.snapshot, &queryCond, &queryResult));

std::vector<XrSpatialEntityEXT> subsumedEntities;
for(uint32_t i = 0; i < queryResult.entityIdCountOutput; ++i) {
    // access planes[i] for merged plane id
    XrSpatialEntityIdEXT entityId = queryResult.entityIds[i];
    XrSpatialEntityIdEXT subsumedUniqueId = subsumedUniqueIds[i];

    // create handle via entityId
  XrSpatialEntityFromIdCreateInfoEXT entityCreateInfo {
    .type = XR_TYPE_SPATIAL_ENTITY_FROM_ID_CREATE_INFO_EXT,
    .entityId = entityId,
  };

  XrSpatialEntityEXT entity = XR_NULL_HANDLE;
  xrCreateSpatialEntityFromIdEXT(spatialContext, &entityCreateInfo, &entity);

  subsumedEntities.push_back(entity);
}

// Cleanup
xrDestroySpatialSnapshotEXT(completion.snapshot);

Filtra las entidades subsumidas

En el siguiente código de ejemplo, se muestra cómo filtrar las entidades con el componente subsumed_by adjunto del resumen de descubrimiento con el filtro, así como consultar el ID de entidad de las entidades subsumidoras.

// Init filter
XrSpatialDiscoveryUniqueEntitiesFilterANDROID filter {
  .type = XR_TYPE_SPATIAL_DISCOVERY_UNIQUE_ENTITIES_FILTER_ANDROID,
};

// Chain filter to the snapshot create info
// WARNING: Chain the filter while include subsumed_by component in the
// componentTypes is invalid
XrSpatialDiscoverySnapshotCreateInfoEXT discoverySnapshotCreateInfo {
  .type = XR_TYPE_SPATIAL_DISCOVERY_SNAPSHOT_CREATE_INFO_EXT,
  .next = &filter
};

waitUntilReady(future);

// Complete async operation.
XrCreateSpatialDiscoverySnapshotCompletionInfoEXT
  createSnapshotCompletionInfo {
    .type   = XR_TYPE_CREATE_SPATIAL_DISCOVERY_SNAPSHOT_COMPLETION_INFO_EXT,
    .baseSpace = space,
    .time      = updateTime,
    .future    = future,
  };

XrCreateSpatialDiscoverySnapshotCompletionEXT completion {
  XR_TYPE_CREATE_SPATIAL_DISCOVERY_SNAPSHOT_COMPLETION_EXT};

CHK_XR(xrCreateSpatialDiscoverySnapshotCompleteEXT(
           spatialContext, &createSnapshotCompletionInfo,
           &completion));

if(completion.futureResult != XR_SUCCESS) return;

// Subsumed entities has already been filtered out in this snapshot,now query
// Bounded2D to render subsuming planes
std::vector<XrSpatialComponentTypeEXT> queryComponents {
  XR_SPATIAL_COMPONENT_TYPE_BOUNDED_2D_EXT,
};

XrSpatialComponentDataQueryConditionEXT queryCond {
  .type = XR_TYPE_SPATIAL_COMPONENT_DATA_QUERY_CONDITION_EXT,
  .componentTypeCount = 1,
  .componentTypes     = queryComponents.data(),
};

XrSpatialComponentDataQueryResultEXT queryResult {
  .type = XR_TYPE_SPATIAL_COMPONENT_DATA_QUERY_RESULT_EXT,
};

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

// Chain Bounded2D list
std::vector<XrSpatialBounded2DDataEXT> bounded2dData;
bounded2dData.resize(queryResult.entityIdCountOutput);

XrSpatialComponentBounded2DListEXT bounded2dList {
  .type = XR_TYPE_SPATIAL_COMPONENT_BOUNDED_2D_LIST_EXT,
  .boundCount = static_cast<uint32_t>(bounded2dData.size()),
  .bounds = bounded2dData.data(),
};

// Query again
queryResult.next = &bounded2dList;
CHK_XR(xrQuerySpatialComponentDataEXT(
           completion.snapshot, &queryCond, &queryResult));

std::vector<XrSpatialEntityEXT> subsumingPlanes;
for(uint32_t i = 0; i < queryResult.entityIdCountOutput; ++i) {
  // access planes[i] for merged plane id
  XrSpatialEntityIdEXT entityId = queryResult.entityIds[i];

  // create handle via entityId.
  XrSpatialEntityFromIdCreateInfoEXT entityCreateInfo {
    .type = XR_TYPE_SPATIAL_ENTITY_FROM_ID_CREATE_INFO_EXT,
    .entityId = entityId,
  };

  XrSpatialEntityEXT entity = XR_NULL_HANDLE;
  xrCreateSpatialEntityFromIdEXT(spatialContext, &entityCreateInfo, &entity);

  subsumingPlanes.push_back(entity);
}

// Cleanup
xrDestroySpatialSnapshotEXT(completion.snapshot);

Nuevas estructuras

Nuevas constantes de enumeración

  • XR_ANDROID_SPATIAL_COMPONENT_SUBSUMED_BY_EXTENSION_NAME
  • XR_ANDROID_spatial_component_subsumed_by_SPEC_VERSION
  • Extensión de XrSpatialComponentTypeEXT :

    • XR_SPATIAL_COMPONENT_TYPE_SUBSUMED_BY_ANDROID
  • Extensión de XrStructureType :

    • XR_TYPE_SPATIAL_COMPONENT_SUBSUMED_BY_LIST_ANDROID
    • XR_TYPE_SPATIAL_DISCOVERY_UNIQUE_ENTITIES_FILTER_ANDROID

Problemas

Historial de versiones

  • Revisión 1, 2025-11-19 (Brian Chen)

    • Es la descripción inicial de la extensión.