Plane
public final class Plane implements Trackable
Describes the system's current best knowledge of a real-world planar surface.
Summary
Nested types |
|---|
public final class Plane.LabelA semantic description of a |
public final class Plane.State implements Trackable.StateThe representation of the current state of a |
public final class Plane.TypeA simple summary of the normal vector of a |
Public methods |
|
|---|---|
@NonNull AnchorCreateResult |
createAnchor(@NonNull Pose pose)Creates an |
@NonNull StateFlow<@NonNull Plane.State> |
getState()The current state of the |
final @NonNull Plane.Type |
getType() |
static final @NonNull StateFlow<@NonNull Collection<@NonNull Plane>> |
Emits the planes that are currently being tracked in the |
Extension functions |
|
|---|---|
final @NonNull Flowable<@NonNull Plane.State> |
RxJava3PlaneKt.getStateAsFlowable(@NonNull Plane receiver)The current state of the |
Public methods
createAnchor
public @NonNull AnchorCreateResult createAnchor(@NonNull Pose pose)
Creates an Anchor that is attached to this trackable, using the given initial pose in the world coordinate space.
| Throws | |
|---|---|
kotlin.IllegalStateException |
if |
getState
public @NonNull StateFlow<@NonNull Plane.State> getState()
The current state of the Plane.
import androidx.lifecycle.Lifecycle import androidx.lifecycle.repeatOnLifecycle import androidx.xr.arcore.Plane import androidx.xr.runtime.TrackingState import androidx.xr.runtime.math.Pose import androidx.xr.scenecore.scene // Use a coroutine to listen to changes to the set of detected planes. yourCoroutineScope.launch { val activePlanes = mutableMapOf<Plane, Job>() lifecycle.repeatOnLifecycle(Lifecycle.State.RESUMED) { val supervisor = SupervisorJob() val supervisorScope = CoroutineScope(yourCoroutineScope.coroutineContext + supervisor) try { Plane.subscribe(session).collect { planes -> // The list of detected planes has changed. for (plane in planes) { // If a plane doesn't exist in our set of active planes, set up a // coroutine to respond to its state changes. if (!activePlanes.contains(plane)) { val job = supervisorScope.launch { plane.state.collect { // if the plane is not currently reporting as tracked, then // we don't want to render it. if (it.trackingState != TrackingState.TRACKING) return@collect // Transform the pose from its original coordinate space to // one suitable for rendering to the display. val pose = it.centerPose.let { p -> session.scene.perceptionSpace.transformPoseTo( p, session.scene.activitySpace, ) } // This function is where you'll actually render the plane // to the display. renderFunction(pose, it.extents, it.vertices, it.label) } } activePlanes[plane] = job } // Likewise, if a plane exists in the `activePlanes` map, but not in our // `planes` list, it needs to be removed, and its corresponding job // canceled. for (plane in activePlanes.keys.toList()) { if (planes.none { it == plane }) { activePlanes.remove(plane)?.cancel() } } } } } finally { // cancel any coroutines still running. supervisor.cancel() activePlanes.clear() } } }
subscribe
public static final @NonNull StateFlow<@NonNull Collection<@NonNull Plane>> subscribe(@NonNull Session session)
Emits the planes that are currently being tracked in the session.
Only Planes that are TrackingState.TRACKING will be emitted in the Collection. Instances of the same Plane will remain between subsequent emits to the StateFlow as long as they remain tracking.
| Throws | |
|---|---|
kotlin.IllegalStateException |
if |
Extension functions
RxJava3PlaneKt.getStateAsFlowable
public final @NonNull Flowable<@NonNull Plane.State> RxJava3PlaneKt.getStateAsFlowable(@NonNull Plane receiver)
The current state of the Plane.