XR_EXT_spatial_anchor

Name String

XR_EXT_spatial_anchor

Tipo di estensione

Estensione dell'istanza

Numero di interno registrato

763

Revisione

1

Stato della ratifica

Ratificato

Dipendenze di estensioni e versioni

XR_EXT_spatial_entity

Collaboratori

Nihav Jain, Google
Natalie Fleury, Meta
Yuichi Taguchi, Meta
Ron Bessems, Meta
Yin Li, Microsoft
Jimmy Alamparambil, ByteDance
Zhipeng Liu, ByteDance
Jun Yan, ByteDance

Panoramica

Questa estensione si basa su XR_EXT_spatial_entity e consente alle applicazioni di creare ancoraggi spaziali, ovvero punti arbitrari nell'ambiente fisico dell'utente che verranno poi monitorati dal runtime. Il runtime dovrebbe quindi regolare la posizione e l'orientamento dell'origine dell'ancoraggio nel tempo, se necessario, indipendentemente da tutti gli altri spazi e ancoraggi, per garantire che mantenga la mappatura originale rispetto al mondo reale.

Un'ancora che monitora una determinata posizione e un determinato orientamento all'interno di un XrSpatialContextEXT è rappresentata come un'entità spaziale con (o "che ha") il componente XR_SPATIAL_COMPONENT_TYPE_ANCHOR_EXT.

Vantaggio dell'utilizzo degli ancoraggi

Man mano che la comprensione dell'ambiente fisico dell'utente da parte del runtime si aggiorna nel corso della durata di un XrSpatialContextEXT , gli oggetti virtuali potrebbero sembrare allontanarsi dal punto in cui sono stati posizionati dall'applicazione, il che influisce sul realismo dell'applicazione e sulla qualità dell'esperienza utente. Creando un'ancora vicino alla posizione di un oggetto virtuale e quindi eseguendo sempre il rendering di quell'oggetto virtuale in relazione alla sua ancora, un'applicazione può garantire che ogni oggetto virtuale sembri rimanere nella stessa posizione e con lo stesso orientamento nell'ambiente fisico. Inoltre, a differenza di alcuni spazi di riferimento, le ancora non sono interessate dal ricentramento a livello di sistema.

Assistenza per i runtime

Se il runtime supporta le ancora spaziali, deve indicarlo enumerando XR_SPATIAL_CAPABILITY_ANCHOR_EXT in xrEnumerateSpatialCapabilitiesEXT .

Configurazione

La struttura XrSpatialCapabilityConfigurationAnchorEXT è definita come:

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

Descrizioni dei membri

  • type è l'XrStructureType di questa struttura.
  • next è NULL o un puntatore alla struttura successiva in una catena di strutture.
  • capability è un XrSpatialCapabilityEXT .
  • enabledComponentCount è un uint32_t che descrive il conteggio degli elementi nell'array enabledComponents.
  • enabledComponents è un puntatore a un array di XrSpatialComponentTypeEXT .

Le applicazioni possono attivare la funzionalità spaziale XR_SPATIAL_CAPABILITY_ANCHOR_EXT includendo un puntatore a una struttura XrSpatialCapabilityConfigurationAnchorEXT in XrSpatialContextCreateInfoEXT :: capabilityConfigs .

Il runtime deve restituire XR_ERROR_VALIDATION_FAILURE se capability non è XR_SPATIAL_CAPABILITY_ANCHOR_EXT .

Utilizzo valido (implicito)

Componenti garantiti

Un runtime che supporta XR_SPATIAL_CAPABILITY_ANCHOR_EXT deve fornire i seguenti componenti spaziali come componenti garantiti di tutte le entità create o rilevate da questa funzionalità e deve enumerarli in xrEnumerateSpatialCapabilityComponentTypesEXT :

  • XR_SPATIAL_COMPONENT_TYPE_ANCHOR_EXT

Componente Anchor

Dati dei componenti

XR_SPATIAL_COMPONENT_TYPE_ANCHOR_EXT utilizza XrPosef per i suoi dati, che forniscono la posizione e l'orientamento dell'ancoraggio.

Struttura dell'elenco dei componenti per eseguire query sui dati

La struttura XrSpatialComponentAnchorListEXT è definita come:

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

Descrizioni dei membri

  • type è l'XrStructureType di questa struttura.
  • next è NULL o un puntatore alla struttura successiva in una catena di strutture.
  • locationCount è un uint32_t che descrive il conteggio degli elementi nell'array locations.
  • locations è un array di XrPosef .

Il runtime deve restituire XR_ERROR_VALIDATION_FAILURE da xrQuerySpatialComponentDataEXT se XrSpatialComponentAnchorListEXT si trova nella catena XrSpatialComponentDataQueryResultEXT :: next, ma XR_SPATIAL_COMPONENT_TYPE_ANCHOR_EXT non è incluso in XrSpatialComponentDataQueryConditionEXT :: componentTypes .

Il runtime deve restituire XR_ERROR_SIZE_INSUFFICIENT da xrQuerySpatialComponentDataEXT se locationCount è inferiore a XrSpatialComponentDataQueryResultEXT :: entityIdCountOutput .

Utilizzo valido (implicito)

Configurazione

Se XR_SPATIAL_COMPONENT_TYPE_ANCHOR_EXT è enumerato in XrSpatialCapabilityComponentTypesEXT :: componentTypes per una funzionalità, un'applicazione può attivarla includendo l'enumerante nell'elenco XrSpatialCapabilityConfigurationBaseHeaderEXT :: enabledComponents della struttura derivata XrSpatialCapabilityConfigurationBaseHeaderEXT della funzionalità che supporta questo componente.

Questo componente non richiede alcuna configurazione speciale per essere incluso nella catena XrSpatialCapabilityConfigurationBaseHeaderEXT :: next.

Creazione di un ancoraggio spaziale

La funzione xrCreateSpatialAnchorEXT è definita come:

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

Descrizioni dei parametri

L'applicazione può creare un ancoraggio spaziale utilizzando xrCreateSpatialAnchorEXT .

Per ottenere i dati dei componenti aggiornati per un'ancora, passa il valore compilato in anchorEntity a XrSpatialUpdateSnapshotCreateInfoEXT :: entities durante la creazione di uno snapshot. L'applicazione può utilizzare anchorEntityId per identificare in modo univoco questa ancora nell'array XrSpatialComponentDataQueryResultEXT :: entityIds quando utilizza xrQuerySpatialComponentDataEXT .

Il runtime deve restituire XR_ERROR_VALIDATION_FAILURE da xrCreateSpatialAnchorEXT se XR_SPATIAL_CAPABILITY_ANCHOR_EXT non è stato configurato per spatialContext . Consulta la sezione Configurazione per scoprire come configurare un XrSpatialContextEXT per la funzionalità XR_SPATIAL_CAPABILITY_ANCHOR_EXT.

L'ancora rappresentata da anchorEntity è valida solo per la durata di spatialContext o fino a quando l'applicazione non chiama xrDestroySpatialEntityEXT, a seconda dell'evento che si verifica per primo. Altre estensioni potrebbero offrire funzioni per rendere persistente questo ancoraggio appena creato in più XrSession o per condividerlo tra i limiti di processo con altre applicazioni.

Un'ancora appena creata, finché non viene eliminata, deve essere rilevabile nel contesto spaziale principale. Ciò significa che il runtime deve includere anchorEntityId nello snapshot creato utilizzando xrCreateSpatialDiscoverySnapshotAsyncEXT per spatialContext se l'ancoraggio corrisponde ai criteri di rilevamento impostati in XrSpatialDiscoverySnapshotCreateInfoEXT . L'ancoraggio appena creato potrebbe essere rilevabile anche in altri contesti spaziali configurati con XR_SPATIAL_CAPABILITY_ANCHOR_EXT, anche se con un XrSpatialEntityIdEXT diverso, poiché un XrSpatialEntityIdEXT specifico è univoco per il suo XrSpatialContextEXT .

Utilizzo valido (implicito)

Codici di risposta

Operazione riuscita

  • XR_SUCCESS
  • XR_SESSION_LOSS_PENDING

Errore

  • 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 (se XR_ANDROID_spatial_entity_bound_anchor è abilitato)
  • XR_ERROR_SPATIAL_ENTITY_ID_INVALID_EXT (se XR_ANDROID_spatial_entity_bound_anchor è abilitato)

La struttura XrSpatialAnchorCreateInfoEXT è definita come:

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

Descrizioni dei membri

  • type è l'XrStructureType di questa struttura.
  • next è NULL o un puntatore alla struttura successiva in una catena di strutture.
  • baseSpace è l'XrSpace in cui viene applicato pose.
  • time è la XrTime in cui si trova baseSpace (e viene applicato pose).
  • pose è la località dell'entità di ancoraggio.

Utilizzo valido (implicito)

Query Anchor Pose

Dopo aver creato l'ancoraggio, il runtime dovrebbe quindi regolare la sua posizione e il suo orientamento nel tempo rispetto ad altri spazi per mantenere il miglior allineamento possibile con la sua posizione reale originale, anche se ciò modifica la relazione dell'ancoraggio con l'originale XrSpatialAnchorCreateInfoEXT :: baseSpace utilizzato per inizializzarlo.

L'applicazione può utilizzare xrCreateSpatialUpdateSnapshotEXT con l'XrSpatialEntityEXT dell'ancoraggio per creare un nuovo XrSpatialSnapshotEXT e poi eseguire una query sul componente XR_SPATIAL_COMPONENT_TYPE_ANCHOR_EXT da quello snapshot utilizzando xrQuerySpatialComponentDataEXT . L'applicazione può aggiungere XrSpatialComponentAnchorListEXT a XrSpatialComponentDataQueryResultEXT :: next per recuperare i dati sulla posizione più recenti per gli ancoraggi.

Il runtime può impostare lo stato di monitoraggio di un'ancora appena creata su XR_SPATIAL_ENTITY_TRACKING_STATE_PAUSED_EXT . L'applicazione deve leggere solo lo stato dell'entità di ancoraggio fornito in XrSpatialComponentDataQueryResultEXT :: entityStates e i dati del componente di ancoraggio dell'entità se lo stato di monitoraggio è XR_SPATIAL_ENTITY_TRACKING_STATE_TRACKING_EXT .

Linee guida per l'utilizzo degli ancoraggi

  • La posa di ogni ancora si regola indipendentemente da qualsiasi altra ancora o spazio. Gli oggetti virtuali ancorati separatamente potrebbero spostarsi o ruotare l'uno rispetto all'altro, interrompendo la gerarchia spaziale nei casi in cui questi oggetti virtuali dovrebbero rimanere in posizione l'uno rispetto all'altro. In questi casi, l'applicazione dovrebbe riutilizzare la stessa ancora per tutti gli oggetti virtuali che non si muovono l'uno rispetto all'altro.
  • L'applicazione deve eliminare tutti gli handle XrSpatialEntityEXT per le ancora che non vengono più utilizzate per liberare le risorse che il runtime potrebbe utilizzare per monitorare queste ancora.

Esempio di codice

Configura la funzionalità di ancoraggio

L'esempio seguente mostra come configurare la funzionalità di ancoraggio durante la creazione di un contesto spaziale.

// 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 ancoraggio spaziale e ottieni la sua posizione

L'esempio seguente mostra come creare un ancoraggio spaziale e ottenere la sua posizione in ogni frame.

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

Nuovi comandi

Nuove strutture

Nuove costanti enum

  • XR_EXT_SPATIAL_ANCHOR_EXTENSION_NAME
  • XR_EXT_spatial_anchor_SPEC_VERSION
  • Estensione di XrSpatialCapabilityEXT :

    • XR_SPATIAL_CAPABILITY_ANCHOR_EXT
  • Estensione di XrSpatialComponentTypeEXT :

    • XR_SPATIAL_COMPONENT_TYPE_ANCHOR_EXT
  • Estensione di XrStructureType :

    • XR_TYPE_SPATIAL_ANCHOR_CREATE_INFO_EXT
    • XR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_ANCHOR_EXT
    • XR_TYPE_SPATIAL_COMPONENT_ANCHOR_LIST_EXT

Problemi

Cronologia delle versioni

  • Revisione 1, 10/07/2024 (Nihav Jain, Google)

    • Descrizione iniziale dell'estensione