XR_ANDROID_spatial_component_subsumed_by

Chaîne de nom

XR_ANDROID_spatial_component_subsumed_by

Type d'extension

Extension d'instance

Numéro d'extension enregistré

792

Révision

1

État de ratification

Non ratifié

Dépendances d'extension et de version

XR_EXT_spatial_entity
et
XR_EXT_spatial_plane_tracking

Date de dernière modification

2025-08-19

État de la propriété intellectuelle

Aucune réclamation connue concernant la propriété intellectuelle.

Participants

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

Présentation

Cette extension s'appuie sur XR_EXT_spatial_entity et fournit un nouveau composant pour XR_SPATIAL_CAPABILITY_PLANE_TRACKING_EXT afin d'exposer l'élément XrSpatialEntityIdEXT qui englobe l'entité actuelle.

Lorsque l'environnement d'exécution a acquis suffisamment d'informations sur l'environnement pour détecter que deux plans suivis sont en fait identiques, le composant XR_SPATIAL_COMPONENT_TYPE_SUBSUMED_BY_ANDROID avec l'ID de l'un des plans est associé à l'autre. À partir de ce moment, l'application n'a plus besoin de traiter que l'entité qui ne possède pas le composant XR_SPATIAL_COMPONENT_TYPE_SUBSUMED_BY_ANDROID.

Cette extension introduit également un nouveau filtre, que l'application peut enchaîner à XrSpatialDiscoverySnapshotCreateInfoEXT pour filtrer toutes les entités qui possèdent le composant XR_SPATIAL_COMPONENT_TYPE_SUBSUMED_BY_ANDROID.

Autorisations

Les applications Android doivent disposer de l'autorisation android.permission.SCENE_UNDERSTANDING_COARSE dans leur fichier manifeste, car cette extension suit les plans dans l'environnement. L'autorisation android.permission.SCENE_UNDERSTANDING_COARSE est considérée comme dangereuse.

(niveau de protection : dangereux)

Compatibilité des environnements d'exécution

Si l'environnement d'exécution est capable d'englober un plan dans un autre, il doit l'indiquer en énumérant XR_SPATIAL_COMPONENT_TYPE_SUBSUMED_BY_ANDROID comme composant compatible pour la fonctionnalité XR_SPATIAL_CAPABILITY_PLANE_TRACKING_EXT dans xrEnumerateSpatialCapabilityComponentTypesEXT .

Toutes les données de composant de l'entité associée XR_SPATIAL_COMPONENT_TYPE_SUBSUMED_BY_ANDROID doivent être identiques à l'entité qui l'englobe.

Composant englobé par

Données du composant

XR_SPATIAL_COMPONENT_TYPE_SUBSUMED_BY_ANDROID utilise la structure XrSpatialEntityIdEXT pour ses données, qui représente l'ID de l'entité englobante.

Structure de la liste des composants pour interroger les données

La structure XrSpatialComponentSubsumedByListANDROID est définie comme suit :

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

Descriptions des membres

  • type est le XrStructureType de cette structure.
  • next est NULL ou un pointeur vers la structure suivante dans une chaîne de structures.
  • subsumedUniqueIdCount est un uint32_t décrivant le nombre d'éléments dans le tableau subsumedUniqueIds.
  • subsumedUniqueIds est un tableau de XrSpatialEntityIdEXT .

L'application peut interroger le composant XR_SPATIAL_COMPONENT_TYPE_SUBSUMED_BY_ANDROID des entités spatiales dans un XrSpatialSnapshotEXT en ajoutant XR_TYPE_SPATIAL_COMPONENT_SUBSUMED_BY_LIST_ANDROID à la chaîne suivante du XrSpatialComponentDataQueryResultEXT .

L'environnement d'exécution doit renvoyer XR_ERROR_VALIDATION_FAILURE à partir de xrQuerySpatialComponentDataEXT si XR_TYPE_SPATIAL_COMPONENT_SUBSUMED_BY_LIST_ANDROID se trouve dans la chaîne suivante de XrSpatialComponentDataQueryResultEXT :: next, mais que XR_SPATIAL_COMPONENT_TYPE_SUBSUMED_BY_ANDROID n'est pas inclus dans XrSpatialComponentDataQueryConditionEXT :: componentTypes .

L'environnement d'exécution doit renvoyer XR_ERROR_SIZE_INSUFFICIENT à partir de xrQuerySpatialComponentDataEXT si subsumedUniqueIdCount est inférieur à XrSpatialComponentDataQueryResultEXT :: entityIdCountOutput .

Utilisation valide (implicite)

  • L'extension XR_ANDROID_spatial_component_subsumed_by doit être activée avant d'utiliser XrSpatialComponentSubsumedByListANDROID.
  • type doit être XR_TYPE_SPATIAL_COMPONENT_SUBSUMED_BY_LIST_ANDROID
  • next doit être NULL ou un pointeur valide vers la structure suivante dans une chaîne de structures
  • subsumedUniqueIds doit être un pointeur vers un tableau de valeurs subsumedUniqueIdCount XrSpatialEntityIdEXT.
  • Le paramètre subsumedUniqueIdCount doit être supérieur à 0

Configuration

Si XR_SPATIAL_COMPONENT_TYPE_SUBSUMED_BY_ANDROID est énuméré dans XrSpatialCapabilityComponentTypesEXT :: componentTypes pour la fonctionnalité XR_SPATIAL_CAPABILITY_PLANE_TRACKING_EXT, l'application peut l'activer en incluant l'enum dans la liste XrSpatialCapabilityConfigurationBaseHeaderEXT :: enabledComponents de la structure dérivée XrSpatialCapabilityConfigurationBaseHeaderEXT de la fonctionnalité qui prend en charge ce composant.

Filtrer les entités englobées

La structure XrSpatialDiscoveryUniqueEntitiesFilterANDROID est définie comme suit :

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

Descriptions des membres

  • type est le XrStructureType de cette structure.
  • next est NULL ou un pointeur vers la structure suivante dans une chaîne de structures.

L'application peut inclure XrSpatialDiscoveryUniqueEntitiesFilterANDROID dans la chaîne next de XrSpatialDiscoverySnapshotCreateInfoEXT pour obtenir un instantané avec des entités qui ne sont pas englobées par une autre entité.

Si les applications enchaînent XrSpatialDiscoveryUniqueEntitiesFilterANDROID à XrSpatialDiscoverySnapshotCreateInfoEXT tout en incluant le composant XR_SPATIAL_COMPONENT_TYPE_SUBSUMED_BY_ANDROID dans XrSpatialDiscoverySnapshotCreateInfoEXT :: componentTypes , l'environnement d'exécution doit renvoyer XR_ERROR_VALIDATION_FAILURE .

Si l'application enchaîne XrSpatialDiscoveryUniqueEntitiesFilterANDROID à XrSpatialDiscoverySnapshotCreateInfoEXT, mais ne répertorie aucun composant dans XrSpatialDiscoverySnapshotCreateInfoEXT :: componentTypes, l'environnement d'exécution doit inclure toutes les entités spatiales dans l'instantané qui possèdent l'ensemble de composants énumérés dans XrSpatialCapabilityConfigurationBaseHeaderEXT :: enabledComponents pour les fonctionnalités configurées pour spatialContext, à l'exception des entités qui possèdent le composant XR_SPATIAL_COMPONENT_TYPE_SUBSUMED_BY_ANDROID.

Utilisation valide (implicite)

Exemple de code

Configurer la fonctionnalité de suivi des plans

L'exemple de code suivant montre comment créer un contexte spatial avec la fonctionnalité XR_SPATIAL_CAPABILITY_PLANE_TRACKING_EXT qui prend en charge XR_SPATIAL_COMPONENT_TYPE_SUBSUMED_BY_ANDROID .

// Check runtime supported capabilities
uint32_t capabilityCount = 0;
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;
}

// Enumerate supported components for plane tracking capability
XrSpatialCapabilityComponentTypesEXT planeComponents{
  .type = XR_TYPE_SPATIAL_CAPABILITY_COMPONENT_TYPES_EXT,
};
CHK_XR(xrEnumerateSpatialCapabilityComponentTypesEXT(instance, systemId, XR_SPATIAL_CAPABILITY_PLANE_TRACKING_EXT, &planeComponents));
std::vector<XrSpatialComponentTypeEXT> planeCapabilityComponents(planeComponents.componentTypeCountOutput);
planeComponents.componentTypeCapacityInput = planeCapabilityComponents.size();
planeComponents.componentTypes = planeCapabilityComponents.data();
CHK_XR(xrEnumerateSpatialCapabilityComponentTypesEXT(instance, systemId, XR_SPATIAL_CAPABILITY_PLANE_TRACKING_EXT, &planeComponents));

const auto supportsComponent = [&planeCapabilityComponents](XrSpatialComponentTypeEXT component) {
  return std::find(planeCapabilityComponents.begin(), planeCapabilityComponents.end(), component) != planeCapabilityComponents.end();
};


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

if (supportsComponent(XR_SPATIAL_COMPONENT_TYPE_SUBSUMED_BY_ANDROID)) {
  planeTrackingComponents.push_back(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))

Interroger les données du composant

L'exemple de code suivant montre comment interroger les données du composant XR_SPATIAL_COMPONENT_TYPE_SUBSUMED_BY_ANDROID à partir du contexte configuré avec XR_SPATIAL_CAPABILITY_PLANE_TRACKING_EXT .

// previously created
XrSpatialSnapshotEXT snapshot;

// 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(
           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(
           snapshot, &queryCond, &queryResult));

for (uint32_t i = 0; i < queryResult.entityIdCountOutput; ++i) {
  // Plane was subsumed, remove it from processing logic
  // removeEntityFromProcessingLogic(queryResult.entityIds[i], /*replaceWith=*/ subsumedByList.subsumedUniqueIds[i]);
}

// Cleanup
xrDestroySpatialSnapshotEXT(snapshot);

Filtrer les entités englobées

L'exemple de code suivant montre comment filtrer les entités avec le composant XR_SPATIAL_COMPONENT_TYPE_SUBSUMED_BY_ANDROID associé à partir de l'instantané de découverte à l'aide du filtre, ainsi que comment interroger l'ID d'entité des entités englobantes.

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

// Chain filter to the snapshot create info
// WARNING: Chaining 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
};

XrFutureEXT future {XR_NULL_FUTURE_EXT};
CHK_XR(xrCreateSpatialDiscoverySnapshotAsyncEXT(spatialContext, &discoverySnapshotCreateInfo, &future))

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 {
  .type = 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 the various components of the entities.

// Cleanup
xrDestroySpatialSnapshotEXT(completion.snapshot);

Nouvelles structures

Nouvelles constantes enum

  • XR_ANDROID_SPATIAL_COMPONENT_SUBSUMED_BY_EXTENSION_NAME
  • XR_ANDROID_spatial_component_subsumed_by_SPEC_VERSION
  • Extension de XrSpatialComponentTypeEXT :

    • XR_SPATIAL_COMPONENT_TYPE_SUBSUMED_BY_ANDROID
  • Extension de XrStructureType :

    • XR_TYPE_SPATIAL_COMPONENT_SUBSUMED_BY_LIST_ANDROID
    • XR_TYPE_SPATIAL_DISCOVERY_UNIQUE_ENTITIES_FILTER_ANDROID

Problèmes

Historique des versions

  • Révision 1, 19/11/2025 (Brian Chen)

    • Description initiale de l'extension.