XR_EXT_spatial_anchor
Stringa del nome
XR_EXT_spatial_anchor
Tipo di estensione
Estensione dell'istanza
Numero di estensione registrato
763
Revisione
1
Stato di ratifica
Ratificato
Dipendenze di estensione e versione
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 del mondo reale.
Un ancoraggio che monitora una determinata posizione e un determinato orientamento all'interno di un XrSpatialContextEXT è rappresentato come un'entità spaziale con (o "che ha") il XR_SPATIAL_COMPONENT_TYPE_ANCHOR_EXT componente.
Vantaggi dell'utilizzo degli ancoraggi
Man mano che la comprensione dell'ambiente fisico dell'utente da parte del runtime si aggiorna durante la durata di un XrSpatialContextEXT , gli oggetti virtuali potrebbero sembrare allontanarsi da dove sono stati posizionati dall'applicazione, il che influisce sul realismo dell'applicazione e sulla qualità dell'esperienza dell'utente. Creando un ancoraggio vicino a dove è posizionato un oggetto virtuale e poi eseguendo sempre il rendering di quell'oggetto virtuale rispetto al suo ancoraggio, un'applicazione può garantire che ogni oggetto virtuale sembri rimanere nella stessa posizione e nello stesso orientamento nell'ambiente fisico. Inoltre, a differenza di alcuni spazi di riferimento, gli ancoraggi non sono interessati dal ricentramento a livello di sistema.
Assistenza per i runtime
Se il runtime supporta gli ancoraggi 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èNULLo un puntatore alla struttura successiva in una catena di strutture.capabilityè un XrSpatialCapabilityEXT .enabledComponentCountè unuint32_tche descrive il conteggio degli elementi nell'arrayenabledComponents.enabledComponentsè un puntatore a un array di XrSpatialComponentTypeEXT .
Le applicazioni possono abilitare 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)
- L'estensione
XR_EXT_spatial_anchordeve essere abilitata prima di utilizzare XrSpatialCapabilityConfigurationAnchorEXT -
typedeve essereXR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_ANCHOR_EXT -
nextdeve essereNULLo un puntatore valido alla struttura successiva in una catena di strutture -
capabilitydeve essere un valore XrSpatialCapabilityEXT valido -
enabledComponentsdeve essere un puntatore a un array dienabledComponentCountvalori XrSpatialComponentTypeEXT validi - Il parametro
enabledComponentCountdeve essere maggiore di0
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 di ancoraggio
Dati dei componenti
Il 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èNULLo un puntatore alla struttura successiva in una catena di strutture.locationCountè unuint32_tche descrive il conteggio degli elementi nell'arraylocations.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)
- L'estensione
XR_EXT_spatial_anchordeve essere abilitata prima di utilizzare XrSpatialComponentAnchorListEXT -
typedeve essereXR_TYPE_SPATIAL_COMPONENT_ANCHOR_LIST_EXT -
nextdeve essereNULLo un puntatore valido alla struttura successiva in una catena di strutture -
locationsdeve essere un puntatore a un array dilocationCountXrPosef strutture - Il parametro
locationCountdeve essere maggiore di0
Configurazione
Se XR_SPATIAL_COMPONENT_TYPE_ANCHOR_EXT è enumerato in XrSpatialCapabilityComponentTypesEXT :: componentTypes per una determinata funzionalità, un'applicazione può abilitarlo includendo l'enumerazione 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
spatialContextè un XrSpatialContextEXT creato in precedenza utilizzando xrCreateSpatialContextAsyncEXT .createInfoè un puntatore a un XrSpatialAnchorCreateInfoEXT .anchorEntityIdè un puntatore a unXrSpatialEntityIdEXTin cui viene restituito l'ID dell'entità di ancoraggio.anchorEntityè un puntatore a un XrSpatialEntityEXT in cui viene restituito l'handle dell'entità di ancoraggio.
L'applicazione può creare un ancoraggio spaziale utilizzando xrCreateSpatialAnchorEXT .
Per ottenere i dati dei componenti aggiornati per un ancoraggio, passa il valore inserito in anchorEntity a XrSpatialUpdateSnapshotCreateInfoEXT :: entities quando crei uno snapshot. L'applicazione può utilizzare anchorEntityId per identificare in modo univoco questo ancoraggio nell'array XrSpatialComponentDataQueryResultEXT :: entityIds quando utilizzi xrQuerySpatialComponentDataEXT .
Il runtime deve restituire XR_ERROR_VALIDATION_FAILURE da xrCreateSpatialAnchorEXT se XR_SPATIAL_CAPABILITY_ANCHOR_EXT non è stato configurato per spatialContext . Per informazioni su come configurare un XrSpatialContextEXT per la funzionalità XR_SPATIAL_CAPABILITY_ANCHOR_EXT , consulta la sezione Configurazione.
L'ancoraggio rappresentato da anchorEntity è valido solo per la durata di spatialContext o finché l'applicazione non chiama xrDestroySpatialEntityEXT , a seconda di quale si verifica per prima. Altre estensioni potrebbero offrire funzioni per rendere persistente questo ancoraggio appena creato in più XrSession o per condividerlo tra i limiti dei processi con altre applicazioni.
Un ancoraggio appena creato, fino a quando non viene eliminato, 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 determinato XrSpatialEntityIdEXT è univoco per il suo XrSpatialContextEXT .
Utilizzo valido (implicito)
- L'estensione
XR_EXT_spatial_anchordeve essere abilitata prima di chiamare xrCreateSpatialAnchorEXT -
spatialContextdeve essere un handle XrSpatialContextEXT valido -
createInfodeve essere un puntatore a una struttura XrSpatialAnchorCreateInfoEXT valida -
anchorEntityIddeve essere un puntatore a un valoreXrSpatialEntityIdEXT -
anchorEntitydeve essere un puntatore a un handle XrSpatialEntityEXT
Codici restituiti
XR_SUCCESSXR_SESSION_LOSS_PENDING
XR_ERROR_FUNCTION_UNSUPPORTEDXR_ERROR_HANDLE_INVALIDXR_ERROR_INSTANCE_LOSTXR_ERROR_LIMIT_REACHEDXR_ERROR_OUT_OF_MEMORYXR_ERROR_POSE_INVALIDXR_ERROR_RUNTIME_FAILUREXR_ERROR_SESSION_LOSTXR_ERROR_TIME_INVALIDXR_ERROR_VALIDATION_FAILUREXR_ERROR_SPATIAL_ANCHOR_ATTACHABLE_COMPONENT_NOT_FOUND_ANDROID(seXR_ANDROID_spatial_entity_bound_anchorè abilitato)XR_ERROR_SPATIAL_ENTITY_ID_INVALID_EXT(seXR_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èNULLo un puntatore alla struttura successiva in una catena di strutture.baseSpaceè l'XrSpace in cui viene applicatopose.timeè l'XrTimein cui si trovabaseSpace(e viene applicatopose).poseè la posizione dell'entità di ancoraggio.
Utilizzo valido (implicito)
- L'estensione
XR_EXT_spatial_anchordeve essere abilitata prima di utilizzare XrSpatialAnchorCreateInfoEXT -
typedeve essereXR_TYPE_SPATIAL_ANCHOR_CREATE_INFO_EXT -
nextdeve essereNULLo un puntatore valido alla struttura successiva in una catena di strutture . Vedi anche: XrSpatialAnchorParentANDROID -
baseSpacedeve essere un handle XrSpace valido
Eseguire query sulla posa dell'ancoraggio
Dopo la creazione dell'ancoraggio, il runtime dovrebbe regolarne la posizione e l'orientamento nel tempo rispetto ad altri spazi per mantenere il miglior allineamento possibile alla sua posizione originale nel mondo reale, anche se ciò modifica la relazione dell'ancoraggio con l'XrSpatialAnchorCreateInfoEXT originale :: baseSpace utilizzato per inizializzarlo.
L'applicazione può utilizzare xrCreateSpatialUpdateSnapshotEXT con l'XrSpatialEntityEXT dell'ancoraggio per creare un nuovo XrSpatialSnapshotEXT e quindi 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 di posizione più recenti per gli ancoraggi.
Il runtime potrebbe impostare lo stato di monitoraggio di un ancoraggio appena creato 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 ancoraggio si regola indipendentemente da qualsiasi altro ancoraggio 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 lo stesso ancoraggio per tutti gli oggetti virtuali che non si spostano l'uno rispetto all'altro.
- L'applicazione dovrebbe eliminare tutti gli handle XrSpatialEntityEXT per gli ancoraggi non più utilizzati per liberare le risorse che il runtime potrebbe utilizzare per monitorare questi ancoraggi.
Esempio di codice
Configurare la funzionalità di ancoraggio
Il seguente esempio 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));
Creare un ancoraggio spaziale e ottenere la sua posizione
Il seguente esempio mostra come creare un ancoraggio spaziale e ottenere la sua posa 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
- XrSpatialAnchorCreateInfoEXT
- XrSpatialCapabilityConfigurationAnchorEXT
Estensione di XrSpatialComponentDataQueryResultEXT :
Nuove costanti enum
XR_EXT_SPATIAL_ANCHOR_EXTENSION_NAMEXR_EXT_spatial_anchor_SPEC_VERSIONEstensione 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_EXTXR_TYPE_SPATIAL_CAPABILITY_CONFIGURATION_ANCHOR_EXTXR_TYPE_SPATIAL_COMPONENT_ANCHOR_LIST_EXT
Problemi
Perché xrCreateSpatialAnchorEXT restituisce sia un ID entità sia un handle entità?
- Risolto
- Risposta: la funzione xrCreateSpatialAnchorEXT avrebbe potuto fornire solo l'ID entità come output e le applicazioni avrebbero potuto creare un handle entità per quell'ID utilizzando xrCreateSpatialEntityFromIdEXT . Tuttavia, dato l'utilizzo tipico di un ancoraggio in cui le applicazioni eseguono una query sulla posa dell'ancoraggio ogni frame, diventa un buon candidato per essere utilizzato in un "aggiornamento dello snapshot", che richiede handle entità come input. Anticipando questo caso d'uso tipico, xrCreateSpatialAnchorEXT esegue xrCreateSpatialEntityFromIdEXT per conto dell'applicazione e fornisce l'handle entità da utilizzare con xrCreateSpatialUpdateSnapshotEXT .
Cronologia delle versioni
Revisione 1, 10/07/2024 (Nihav Jain, Google)
- Descrizione iniziale dell'estensione