Ottenere i risultati della sessione
Durante l'esecuzione della sessione, le trasformazioni di alcuni oggetti nella scena vengono modificate, così come l'immagine della fotocamera. A volte, queste modifiche non soddisfano le esigenze dell'applicazione e potrebbe essere necessario ottenere i risultati di ogni fotogramma della sessione ed elaborare ulteriormente questi dati. Questo articolo spiega come ottenere e utilizzare questi dati di risultato.
Prima di iniziare
- Comprendere i concetti di base, la composizione e il flusso di lavoro della sessione tramite Introduzione ad ARSession
- Scoprire come creare una sessione
- Scoprire come accedere ai componenti delle funzionalità AR
Ottenere aggiornamenti di InputFrame
È possibile utilizzare l'evento InputFrameUpdate per ottenere aggiornamenti di InputFrame. Questo evento viene attivato solo quando InputFrame cambia nei dati di output di ogni fotogramma della sessione.
Nota
InputFrameUpdate è valido solo nelle sessioni in cui il rendering viene eseguito da EasyAR. In generale, non è valido quando si utilizza AR Foundation o un visore, in questi casi è necessario utilizzare i metodi forniti da queste librerie di terze parti per ottenere gli aggiornamenti dei dati.
Utilizzando InputFrame è possibile ottenere l'immagine della fotocamera fisica, i parametri della fotocamera, il timestamp, la trasformazione della fotocamera fisica rispetto al sistema di coordinate mondiale e lo stato del tracking. Tuttavia, poiché la trasformazione della fotocamera è già stata applicata dalla sessione alla fotocamera virtuale e ad altri oggetti, solitamente non è necessario ottenere la trasformazione della fotocamera tramite InputFrame.
Ottenere l'immagine della fotocamera fisica del fotogramma corrente
È possibile utilizzare il metodo InputFrame.image() per ottenere i dati dell'immagine della fotocamera fisica di tipo Image.
Ad esempio, il seguente codice può ottenere l'immagine della fotocamera fisica quando InputFrame viene aggiornato:
Session.InputFrameUpdate += (inputFrame) => {
using (var image = inputFrame.image())
{
}
};
Attenzione
Quando si utilizzano dati di tipo Image e altri dati di tipo class ottenuti da esso, è necessario assicurarsi che Dispose() venga chiamato correttamente (l'istruzione using nel codice precedente garantisce ciò), altrimenti potrebbero verificarsi perdite di memoria o persino problemi come l'interruzione dell'aggiornamento dell'immagine.
Se è necessario conservare InputFrame o Image per il fotogramma successivo, è necessario aumentare il valore di ARAssembly.ExtraBufferCapacity in base alla quantità di dati conservati, altrimenti potrebbe verificarsi un errore di acquisizione dati a causa di buffer insufficienti.
Se è necessario conservare InputFrame, è inoltre necessario chiamare il metodo Clone() per creare una copia del riferimento, quindi chiamare Dispose() sulla copia quando non è più necessaria.
Poiché il framerate della fotocamera fisica è generalmente inferiore al framerate di rendering, non è possibile ricevere l'evento InputFrameUpdate in ogni fotogramma di rendering. Tuttavia, allo stesso modo, il rendering dell'immagine della fotocamera fisica non viene aggiornato in ogni fotogramma di rendering. Il contenuto dell'immagine per tutti i fotogrammi di rendering fino al successivo evento InputFrameUpdate corrisponde all'immagine del corrente InputFrame.
Nota
L'immagine in InputFrame corrisponde sicuramente allo sfondo della fotocamera virtuale nel fotogramma corrente, ma durante il rendering dello sfondo potrebbe essere stata ridimensionata e ritagliata, quindi è normale che le dimensioni o le proporzioni dell'immagine ottenuta non corrispondano a quelle visualizzate sullo schermo.
Inoltre, è importante notare che i dati dell'immagine restituiti da InputFrame.image() sono leggibili dalla CPU e non sono texture GPU. Se è necessario utilizzare i dati dell'immagine sulla GPU, è necessario caricarli in una texture GPU o ottenere direttamente la texture GPU tramite l'interfaccia CameraImageRenderer.RequestTargetTexture(Action<Camera, RenderTexture>).
[Opzionale] Intercettare il rendering dell'immagine della fotocamera fisica
È possibile utilizzare ARAssembly.CameraImageRenderer per controllare il rendering dell'immagine della fotocamera fisica.
Il seguente codice può interrompere il rendering dell'immagine della fotocamera fisica:
if (Session.Assembly != null && Session.Assembly.CameraImageRenderer.OnSome)
{
Session.Assembly.CameraImageRenderer.Value.enabled = false;
}
Nota: qui è necessario verificare prima se ARAssembly.CameraImageRenderer esiste.
Nota
È possibile interrompere l'aggiornamento dell'immagine tramite il metodo precedente solo nelle sessioni in cui il rendering viene eseguito da EasyAR. In generale, non è valido quando si utilizza AR Foundation o un visore, in questi casi è necessario utilizzare i metodi forniti da queste librerie di terze parti per implementare la funzionalità corrispondente.
Dopo aver interrotto il rendering dell'immagine della fotocamera fisica, l'applicazione può ottenere i dati dell'immagine della fotocamera fisica tramite InputFrame e utilizzare questi dati per un rendering personalizzato.
Ottenere aggiornamenti di transform
È possibile ottenere i dati di transform degli oggetti nella scena dopo ogni aggiornamento della sessione tramite l'evento PostSessionUpdate.
Nota
Per alcune funzionalità (ad esempio Mega), anche se l'immagine non cambia e non viene richiesto esplicitamente un aggiornamento del servizio, il calcolo AR viene eseguito in ogni fotogramma di rendering. Pertanto, se è necessario ottenere tutte le modifiche di transform, è necessario ottenere i dati di transform in ogni fotogramma e non solo in alcuni fotogrammi.
Ottenere il transform della fotocamera virtuale
È possibile ottenere il transform della fotocamera nella scena tramite ARAssembly.Camera.
Session.PostSessionUpdate += () =>
{
var position = Session.Assembly.Camera.transform.position;
var rotation = Session.Assembly.Camera.transform.rotation;
};
Ottenere il transform del target
È possibile ottenere il transform del target nella scena tramite l'oggetto target specifico in uso. Ad esempio, per il tracciamento delle immagini, questo target è l'oggetto su cui si trova il componente ImageTargetController.
Session.PostSessionUpdate += () =>
{
var position = target.transform.position;
var rotation = target.transform.rotation;
};
[Opzionale] Ottenere la pose
La pose è una struttura di dati che descrive la posizione e l'orientamento di un oggetto, solitamente composta da posizione e rotazione. Nelle applicazioni AR, la pose viene solitamente utilizzata per descrivere la posizione e l'orientamento della fotocamera fisica o di un target di tracciamento rispetto a un sistema di riferimento.
Unity non fornisce dati di pose grezzi, poiché la pose viene generalmente utilizzata per guidare il movimento degli oggetti nella scena, che è esattamente il lavoro che la sessione svolge automaticamente. Per il calcolo e il rendering dei contenuti, il transform è sufficiente.
Importante
Prima di leggere i metodi seguenti, si prega di riconsiderare se i dati di transform della fotocamera, dei target di tracciamento e altri oggetti nella scena soddisfano già i requisiti. In genere, dati di pose aggiuntivi non sono necessari.
Se per qualche motivo sono effettivamente necessari dati di pose, è possibile calcolare il valore di pose richiesto tramite il transform nell'evento PostSessionUpdate. In genere, il transform relativo tra target e fotocamera ottenuto in PostSessionUpdate è la pose.
Il seguente codice mostra come ottenere il transform della fotocamera e del target e calcolare la pose relativa tra di loro:
Session.PostSessionUpdate += () =>
{
Pose cameraToWorld = new(Session.Assembly.Camera.transform.position, Session.Assembly.Camera.transform.rotation);
Pose targetToWorld = new(target.transform.position, target.transform.rotation);
Pose worldToTarget = new()
{
position = Quaternion.Inverse(targetToWorld.rotation) * (-targetToWorld.position),
rotation = Quaternion.Inverse(targetToWorld.rotation)
};
Pose cameraToTarget = cameraToWorld.GetTransformedBy(worldToTarget);
};
Attenzione
Se si utilizza contemporaneamente AR Foundation, un visore o altre librerie di terze parti in esecuzione, queste librerie potrebbero modificare anche il transform della fotocamera nella scena. È necessario assicurarsi che la logica di aggiornamento di queste librerie venga completata prima di eseguire i calcoli di pose correlati, altrimenti i risultati potrebbero essere imprecisi. In tali scenari, la pose relativa tra target e origine in PostSessionUpdate è ancora accurata.
[Opzionale] Intercettare aggiornamenti di transform
Durante l'esecuzione della funzionalità AR, il transform degli oggetti nella scena come la fotocamera e i target di tracciamento viene solitamente aggiornato automaticamente dalla sessione. Questi processi di aggiornamento garantiscono la correttezza e la coerenza del rendering AR, quindi non esiste alcun metodo per intercettare questi aggiornamenti.
Tuttavia, se è necessario personalizzare la logica di aggiornamento del transform di un oggetto, è possibile farlo tramite l'evento PostSessionUpdate. Qui è necessario utilizzare un metodo piuttosto complesso:
- Sebbene in genere si debbano collegare i contenuti di rendering come nodi figlio o componenti aggiuntivi sotto gli oggetti controllati dalla sessione, se è necessario personalizzare l'aggiornamento del transform di un oggetto, è necessario rimuovere tale oggetto dalla gerarchia degli oggetti controllati dalla sessione. Ciò significa che questi oggetti non dovrebbero essere nodi figlio degli oggetti controllati dalla sessione.
- Nell'evento PostSessionUpdate, registrare il transform dell'oggetto che si desidera aggiornare personalmente.
- Infine, nell'evento PostSessionUpdate, aggiornare il transform di questi oggetti utilizzando la logica personalizzata in base ai dati forniti dalla sessione.
Nota
L'utilizzo dell'evento PostSessionUpdate è necessario perché solo dopo questo momento la sessione non manipolerà più gli oggetti nella scena.
È importante notare che questo metodo non può essere utilizzato per modificare la fotocamera, poiché richiede una logica più complessa per gestire l'aggiornamento personalizzato della fotocamera.
Inoltre, questo metodo può essere utilizzato solo per personalizzare l'aggiornamento del transform di un oggetto, non per modificare il transform degli oggetti controllati dalla sessione. Se il transform di un oggetto controllato dalla sessione viene modificato esternamente, la sessione sovrascriverà comunque queste modifiche nell'aggiornamento del fotogramma successivo, il che potrebbe influire sulla correttezza di alcuni calcoli.
Attenzione
L'utilizzo di questo metodo richiede di garantire la correttezza del transform dell'oggetto, altrimenti potrebbe causare errori nel rendering AR.
Se si utilizza contemporaneamente AR Foundation, un visore o altre librerie di terze parti, queste librerie potrebbero modificare anche il transform degli oggetti nella scena. È necessario assicurarsi che la logica di aggiornamento di queste librerie non confligga con la logica personalizzata, altrimenti potrebbero verificarsi risultati imprevisti.
Argomenti correlati
- Modalità centro vincola quali trasformazioni di oggetti la sessione modificherà
- Introduzione ai componenti AR di base