Mit ARCore für Jetpack XR können Apps mit grundlegenden Konzepten der Augmented Reality (AR) arbeiten, indem sie Low-Level-Primitive zur Szenenerkennung und Bewegungserkennung verwenden. Verwenden Sie ARCore für Jetpack XR, wenn Sie AR-Inhalte erstellen und planare Daten verwenden oder Inhalte an einem festen Ort im Raum verankern möchten.
Lebenszyklus einer Sitzung
Auf alle Objekte, die von ARCore für Jetpack XR erfasst werden, muss über eine Sitzung zugegriffen werden. Ähnlich wie der Lebenszyklus einer Aktivität haben auch Sitzungsobjekte einen Lebenszyklus, der entsprechend der Verwendung der Funktionen eines Sitzungsobjekts durch Ihre App beibehalten werden muss. Wenn Ihre App eine einzelne XR-fähige Aktivität enthält, sollten Sie den Lebenszyklus der Sitzung mit einer lebenszyklusbewussten Komponente verwalten.
Sitzung erstellen
Eine Sitzung muss erstellt werden, bevor sie verwendet werden kann. Zum Erstellen einer Sitzung muss der Nutzer Ihrer App die Berechtigung android.permission.SCENE_UNDERSTANDING
erteilt haben.
So erstellen Sie eine Sitzung:
when (val result = Session.create(owner)) {
is SessionCreateSuccess -> {
session = result.session
}
is SessionCreatePermissionsNotGranted -> {
// Request android.permission.SCENE_UNDERSTANDING.
}
}
Unter SessionCreateResult
finden Sie Gründe, warum eine Sitzung möglicherweise nicht erstellt werden kann.
Sitzung fortsetzen
Eine Sitzung sollte fortgesetzt werden, wenn Ihre App Statusänderungen von ARCore für Jetpack XR verarbeiten kann. In vielen Fällen geschieht dies im onResume()
-Callback Ihrer Aktivität. In Ihrer App kann die Verarbeitung jedoch bis zur Nutzerinteraktion verzögert werden.
Das folgende Code-Snippet zeigt ein Beispiel für die Fortsetzung einer Sitzung.
when (val result = session.resume()) {
is SessionResumeSuccess -> {
// Session has been created successfully.
// Attach any successful handlers here.
}
is SessionResumePermissionsNotGranted -> {
// Request android.permission.SCENE_UNDERSTANDING.
}
Unter SessionResumeResult
finden Sie Gründe, warum eine Sitzung möglicherweise nicht fortgesetzt werden kann.
Sitzung pausieren
Wenn Ihre Aktivität in den Hintergrund wechselt, können Sie die Sitzung mit Session.pause()
pausieren. Wenn Sie eine Sitzung pausieren, wird das Tracking vorübergehend angehalten, bis die Sitzung fortgesetzt wird. Der Zustand des Wahrnehmungssystems bleibt dabei erhalten.
Sitzung beenden
Wenn Sie eine Sitzung dauerhaft löschen möchten, verwenden Sie Session.destroy()
. Dadurch werden die von der Sitzung verwendeten Ressourcen freigegeben und alle Sitzungsstatus werden gelöscht.
Status der erkannten Flugzeuge abrufen
ARCore für Jetpack XR stellt den Status von Ebenen über eine StateFlow
bereit, die den Status der Ebenen ausgibt. Wenn Sie sich für Flugzeuge in einer Sitzung anmelden, wird Ihre App benachrichtigt, wenn Flugzeuge hinzugefügt, aktualisiert oder entfernt werden.
Plane.subscribe(session).collect { planes ->
// Planes have changed; update plane rendering
}
Eine Ebene hat die folgenden Eigenschaften:
label
: eine semantische Beschreibung einer bestimmtenPlane
. KannWall
,Floor
,Ceiling
oderTable
sein.centerPose
: Die Pose des Mittelpunkts der erkannten Ebene.extents
: Die Abmessungen der erkannten Ebene in Metern.vertices
: Eine Liste von Eckpunkten eines konvexen Polygons, das die Ebene approximiert.
Kollisionstest mit Ebenen durchführen
Ein Treffertest ist eine Methode, mit der die Schnittmenge eines Strahls mit Objekten berechnet wird, die von der Sitzung erfasst werden. Ein gängiger Anwendungsfall für einen Treffertest ist das Anklicken einer Tabelle und das Platzieren eines Objekts an dieser Stelle. Ein Treffertest führt zu einer Liste von Trefferobjekten. Mit anderen Worten: Ein Hit-Test endet nicht beim ersten Objekttreffer. Oft sind Sie jedoch nur an dem ersten Objekttreffer eines bestimmten Typs interessiert.
Verwenden Sie zum Ausführen eines Treffertests Interaction.hitTest()
mit einer Ray
:
val results = Interaction.hitTest(session, ray)
// When interested in the first Table hit:
val tableHit = results.firstOrNull {
val trackable = it.trackable
trackable is Plane && trackable.state.value.label == Plane.Label.Table
}
Inhalte an einem festen Ort im Raum verankern
Verwenden Sie einen Anchor
, um virtuellen Objekten eine Position in der realen Welt zuzuweisen. Mit einem Ankerobjekt kann Ihre App einen festen Ort im physischen Raum im Blick behalten.
Ein Anker wird mit einem Pose
erstellt, der relativ zu einem vorhandenen Trackable
interpretiert werden kann oder nicht.
Anker relativ zu einem Trackable erstellen
Ein Anker wird relativ zu einem Trackable
erstellt, z. B. einem Plane
. Dadurch folgt der Anker dem angehängten Trackable
, wenn er sich durch den Raum bewegt.
val anchor = trackable.createAnchor(pose)
Anker ohne Trackable erstellen
So erstellen Sie einen Anker, der nicht an eine Trackable
angehängt ist:
when (val result = Anchor.create(session, pose)) {
is AnchorCreateSuccess -> // ...
else -> // handle failure
}
Entität an einen Anker anhängen
Wenn Sie ein Modell an diesem Ort rendern möchten, erstellen Sie einen GltfModel
und legen Sie seine Pose auf die des Ankers fest. Das Modell muss ausgeblendet sein, wenn die TrackingState
des Ankers Stopped
ist.
// renderSession is androidx.xr.core.Session
anchor.state.collect { state ->
if (state.trackingState == TrackingState.Tracking) {
gltfEntity.setPose(
renderSession.perceptionSpace.transformPoseTo(state.pose, renderSession.activitySpace)
)
} else if (state.trackingState == TrackingState.Stopped) {
entity.setHidden(true)
}
}
TrackingState
Jede Trackable
hat eine TrackingState
, die vor der Verwendung geprüft werden sollte.
Bei einem Trackable
mit einer TrackableState
von Tracking
wird die Pose
vom System aktiv aktualisiert. Ein Trackable
mit dem Wert Paused
kann in Zukunft zu Tracking
werden, während ein Trackable
mit dem Wert Stopped
niemals zu Tracking
wird.
Anker während der Sitzungen beibehalten
Ein nicht persistenter Anker verschwindet, nachdem eine Sitzung beendet wurde. Wenn Sie einen Anker speichern, merkt sich Ihre App die Position dieses Ankers in den privaten App-Daten. Dieser Anker kann in einer nachfolgenden Sitzung abgerufen werden und ist an derselben Position auf der Welt verankert.
Verwenden Sie anchor.persist()
, um einen Anker zu speichern, wie hier gezeigt:
val uuid = anchor.persist()
Ihre App kann den Anker mithilfe von UUID
in einer zukünftigen Sitzung abrufen:
when (val result = Anchor.load(session, uuid)) {
is AnchorCreateSuccess -> // Loading was successful. The anchor is stored in result.anchor.
else -> // handle failure
}
Wenn Sie keinen Anker mehr benötigen, rufen Sie unpersist()
an. Dadurch wird der Anker aus dem Speicher Ihrer App entfernt und die angegebene UUID kann nicht mehr für Aufrufe von Anchor.load()
abgerufen werden.
Anchor.unpersist(session, uuid)
Ihre App kann auch eine Liste aller gespeicherten Anker anfordern, die sich noch im Speicher Ihrer App befinden:
val uuids = Anchor.getPersistedAnchorUuids(session)