Ergebnisse der session abrufen
Während des Betriebs der session werden die transform einiger Objekte in der Szene sowie das Kamerabild geändert. Manchmal erfüllen diese Änderungen die Anforderungen der Anwendung nicht ausreichend, und es kann erforderlich sein, die Ergebnisse jedes Frames der session abzurufen und diese Daten weiterzuverarbeiten. Dieser Artikel erklärt, wie diese Ergebnisdaten abgerufen und verwendet werden.
Vorbereitung
- Grundlegendes Verständnis von session-Konzepten, Komponenten und Arbeitsabläufen durch Einführung in ARSession
- Wissen, wie eine session erstellt wird
- Wissen, wie auf AR-Funktionskomponenten zugegriffen wird
Aktualisierungen von InputFrame abrufen
Mit dem Ereignis InputFrameUpdate können Aktualisierungen von InputFrame abgerufen werden. Dieses Ereignis wird nur ausgelöst, wenn sich das InputFrame in den Ausgabedaten der session pro Frame ändert.
Anmerkung
InputFrameUpdate ist nur in sessions wirksam, bei denen EasyAR das Rendering durchführt. Im Allgemeinen ist es bei Verwendung von AR Foundation oder Headsets nicht wirksam. In diesen Fällen müssen die von diesen Drittanbieter-Bibliotheken bereitgestellten Methoden zum Abrufen von Datenaktualisierungen verwendet werden.
Mit InputFrame können physische Kamerabilder, Kameraparameter, Zeitstempel, die Transformation der physischen Kamera relativ zum Weltkoordinatensystem und der Tracking-Status abgerufen werden. Da die Kameratransformation jedoch bereits von der session auf virtuelle Kameras und andere Objekte angewendet wird, ist es normalerweise nicht notwendig, die Kameratransformation über InputFrame abzurufen.
Physisches Kamerabild des aktuellen Frames abrufen
Die Methode InputFrame.image() kann verwendet werden, um Bilddaten des physischen Kamerabilds vom Typ Image abzurufen.
Der folgende Code ruft beispielsweise das physische Kamerabild ab, wenn InputFrame aktualisiert wird:
Session.InputFrameUpdate += (inputFrame) => {
using (var image = inputFrame.image())
{
}
};
Vorsicht
Bei der Verwendung von Daten des Typs Image und anderer daraus abgerufener class-Typen muss sichergestellt werden, dass Dispose() ordnungsgemäß aufgerufen wird (im obigen Code wird dies durch die using-Anweisung gewährleistet). Andernfalls kann es zu Speicherlecks oder Problemen wie eingefrorenen Bildern kommen.
Wenn InputFrame oder Image für die Verwendung im nächsten Frame beibehalten werden müssen, muss der Wert von ARAssembly.ExtraBufferCapacity entsprechend der zu behaltenden Datenmenge erhöht werden. Andernfalls kann es aufgrund unzureichender Pufferkapazität zu Fehlern beim Datenabruf kommen.
Um InputFrame beizubehalten, muss außerdem die Methode Clone() aufgerufen werden, um eine Referenzkopie zu erstellen. Diese Kopie muss dann mit Dispose() freigegeben werden, wenn sie nicht mehr benötigt wird.
Da die Bildrate der physischen Kamera normalerweise niedriger ist als die Render-Framerate, wird das Ereignis InputFrameUpdate nicht in jedem Render-Frame ausgelöst. Ebenso wird das Rendering des physischen Kamerabilds nicht in jedem Render-Frame aktualisiert. Der Bildinhalt aller Render-Frames bis zum nächsten Auslösen von InputFrameUpdate entspricht dem Bild des aktuellen InputFrame.
Anmerkung
Das Bild in InputFrame stimmt immer mit dem Hintergrundbild der virtuellen Kamera im aktuellen Frame überein. Das Hintergrundbild kann jedoch beim Rendering skaliert und beschnitten werden. Daher ist es normal, wenn die abgerufene Bildgröße oder das Seitenverhältnis nicht mit der Bildschirmanzeige übereinstimmt.
Es ist auch wichtig zu beachten, dass die von InputFrame.image() zurückgegebenen Bilddaten CPU-lesbar sind und keine GPU-Textur darstellen. Wenn die Bilddaten auf der GPU verwendet werden sollen, müssen sie in eine GPU-Textur hochgeladen werden, oder es kann direkt über die Schnittstelle CameraImageRenderer.RequestTargetTexture(Action<Camera, RenderTexture>) auf die GPU-Textur zugegriffen werden.
[Optional] Rendering des physischen Kamerabilds abfangen
Die Zeichnung des physischen Kamerabilds kann mit ARAssembly.CameraImageRenderer gesteuert werden.
Der folgende Code stoppt das Rendering des physischen Kamerabilds:
if (Session.Assembly != null && Session.Assembly.CameraImageRenderer.OnSome)
{
Session.Assembly.CameraImageRenderer.Value.enabled = false;
}
Es ist wichtig, zunächst zu prüfen, ob ARAssembly.CameraImageRenderer existiert.
Anmerkung
Das Rendering kann nur auf diese Weise gestoppt werden, wenn EasyAR für das Rendering verantwortlich ist. Im Allgemeinen ist dies bei Verwendung von AR Foundation oder Headsets nicht wirksam. In diesen Fällen müssen die von diesen Drittanbieter-Bibliotheken bereitgestellten Methoden verwendet werden, um die entsprechende Funktionalität zu implementieren.
Nachdem das Rendering des physischen Kamerabilds gestoppt wurde, kann die Anwendung die Bilddaten der physischen Kamera über InputFrame abrufen und für benutzerdefiniertes Rendering verwenden.
Transform-Aktualisierungen abrufen
Transform-Daten von Objekten in der Szene nach jeder Frame-Aktualisierung der session können über das Ereignis PostSessionUpdate abgerufen werden.
Anmerkung
Für einige Funktionen (z. B. Mega) läuft die AR-Berechnung in jedem Render-Frame, auch wenn sich das Bild nicht ändert und kein expliziter Service-Update angefordert wird. Daher müssen Transform-Daten in jedem Frame abgerufen werden, um alle Änderungen zu erfassen, nicht nur in bestimmten Frames.
Transform der virtuellen Kamera abrufen
Die Transform der Kamera in der Szene kann über ARAssembly.Camera abgerufen werden.
Session.PostSessionUpdate += () =>
{
var position = Session.Assembly.Camera.transform.position;
var rotation = Session.Assembly.Camera.transform.rotation;
};
Transform des targets abrufen
Die Transform des targets in der Szene kann über das verwendete target-Objekt abgerufen werden. Für die Bildverfolgung ist dieses target beispielsweise das Objekt, an dem die ImageTargetController-Komponente angehängt ist.
Session.PostSessionUpdate += () =>
{
var position = target.transform.position;
var rotation = target.transform.rotation;
};
[Optional] Pose abrufen
Eine Pose ist eine Datenstruktur, die die Position und Ausrichtung eines Objekts beschreibt, normalerweise bestehend aus Position und Rotation. In AR-Anwendungen wird die Pose typischerweise verwendet, um die Position und Ausrichtung der physischen Kamera oder eines Tracking-Ziels relativ zu einem Referenzsystem zu beschreiben.
Unity stellt keine Roh-Pose-Daten bereit, da Posen normalerweise verwendet werden, um die Bewegung von Objekten in der Szene anzutreiben – eine Aufgabe, die automatisch von der session erledigt wird. Für Inhaltsberechnung und Rendering sind Transforms ausreichend.
Wichtig
Bevor Sie die folgenden Methoden lesen, überlegen Sie bitte erneut, ob die Transform-Daten der Kamera, der Tracking-Ziele usw. in der Szene bereits Ihren Anforderungen genügen. In der Regel sind zusätzliche Pose-Daten nicht erforderlich.
Wenn Pose-Daten aus bestimmten Gründen dennoch benötigt werden, können sie im PostSessionUpdate-Ereignis aus den Transform-Daten berechnet werden. Normalerweise entspricht der relative Transform zwischen target und camera, der in PostSessionUpdate abgerufen wird, der Pose.
Der folgende Code zeigt, wie der Transform von camera und target abgerufen und die relative Pose zwischen ihnen berechnet wird:
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);
};
Vorsicht
Wenn Sie gleichzeitig AR Foundation, Headsets oder andere Drittanbieter-Bibliotheken verwenden, können diese auch den Transform der Kamera in der Szene ändern. Stellen Sie sicher, dass die Aktualisierungslogik dieser Bibliotheken abgeschlossen ist, bevor Pose-Berechnungen durchgeführt werden, da die Ergebnisse sonst ungenau sein können. In solchen Szenarien bleibt die relative Pose zwischen target und origin in PostSessionUpdate jedoch korrekt.
[Optional] Transform-Aktualisierungen abfangen
Während des Betriebs der AR-Funktionen werden die Transforms von Objekten wie Kameras und Tracking-Zielen in Unity normalerweise automatisch von der session aktualisiert. Diese Aktualisierungen gewährleisten die Korrektheit und Konsistenz des AR-Renderings. Daher gibt es keine Möglichkeit, diese Aktualisierungen abzufangen.
Wenn Sie jedoch eine benutzerdefinierte Aktualisierungslogik für den Transform eines Objekts benötigen, können Sie das Ereignis PostSessionUpdate nutzen. Hierfür ist ein etwas aufwändigerer Ansatz erforderlich:
- Obwohl Rendering-Inhalte normalerweise als untergeordnete Knoten oder zusätzliche Komponenten an von der session gesteuerten Objekten angehängt werden sollten, müssen diese Objekte aus der Hierarchie der session-gesteuerten Objekte entfernt werden, wenn ihre Transform-Aktualisierung angepasst werden soll. Das bedeutet, diese Objekte sollten keine untergeordneten Knoten session-gesteuerter Objekte sein.
- Notieren Sie im PostSessionUpdate-Ereignis die Transform der Objekte, deren Aktualisierung angepasst werden soll.
- Aktualisieren Sie schließlich im PostSessionUpdate-Ereignis die Transform dieser Objekte mithilfe der von der session bereitgestellten Daten und Ihrer benutzerdefinierten Logik.
Anmerkung
Die Verwendung des PostSessionUpdate-Ereignisses ist erforderlich, da die session erst nach diesem Zeitpunkt keine Operationen an Objekten in der Szene mehr vornimmt.
Beachten Sie, dass diese Methode nicht zur Änderung der Kamera verwendet werden kann. Für benutzerdefinierte Kameraaktualisierungen ist eine komplexere Logik erforderlich.
Außerdem kann diese Methode nur zur benutzerdefinierten Aktualisierung von Objekt-Transforms verwendet werden, nicht zur Änderung der Transforms von session-gesteuerten Objekten. Wenn der Transform eines session-gesteuerten Objekts extern geändert wird, überschreibt die session diese Änderung im nächsten Update-Frame, was die Berechnungskorrektheit beeinträchtigen kann.
Vorsicht
Bei dieser Methode müssen Sie sicherstellen, dass die Objekt-Transforms korrekt sind, da sonst AR-Rendering-Fehler auftreten können.
Wenn Sie gleichzeitig AR Foundation, Headsets oder andere Drittanbieter-Bibliotheken verwenden, können diese auch die Transforms von Objekten in der Szene ändern. Stellen Sie sicher, dass sich deren Aktualisierungslogik nicht mit Ihrer benutzerdefinierten Logik überschneidet, da dies zu unerwarteten Ergebnissen führen kann.
Verwandte Themen
- Zentrumsmodus schränkt ein, welche Objekt-Transforms von der session geändert werden
- Einführung in AR-Basiskomponenten