Dunfey · Hotel WWDC as data, est. 1983
Front desk everything
Years
Topics

2024 Spatial Computing

WWDC24 · 15 min · Spatial Computing

Create enhanced spatial computing experiences with ARKit

Learn how to create captivating immersive experiences with ARKit’s latest features. Explore ways to use room tracking and object tracking to further engage with your surroundings. We’ll also share how your app can react to changes in your environment’s lighting on this platform. Discover improvements in hand tracking and plane detection which can make your spatial experiences more intuitive.

Watch at developer.apple.com ↗

Transcript all transcripts

Chapters

Code shown on screen · 7 snippets

RoomTrackingProvider swift · at 3:35 ↗
// RoomTrackingProvider

@available(visionOS, introduced: 2.0)
public final class RoomTrackingProvider: DataProvider, Sendable {

    /// The room which a person is currently in, if any.
    public var currentRoomAnchor: RoomAnchor? { get }

    /// An async sequence of all anchor updates.
    public var anchorUpdates: AnchorUpdateSequence<RoomAnchor> { get }

    ...
}
RoomAnchor swift · at 4:20 ↗
@available(visionOS, introduced: 2.0)
public struct RoomAnchor: Anchor, Sendable, Equatable {
    /// True if this is the room which a person is currently in.
    public var isCurrentRoom: Bool { get }

    /// Get the geometry of the mesh in the anchor's coordinate system.
    public var geometry: MeshAnchor.Geometry { get }
    /// Get disjoint mesh geometries of a given classification.
    public func geometries(of classification: MeshAnchor.MeshClassification) -> 
        [MeshAnchor.Geometry]

    /// True if this room contains the given point.
    public func contains(_ point: SIMD3<Float>) -> Bool
   
    /// Get the IDs of the plane anchors associated with this room.
    public var planeAnchorIDs: [UUID] { get }
    /// Get the IDs of the mesh anchors associated with this room.
    public var meshAnchorIDs: [UUID] { get }
}
Load Object Tracking referenceobject swift · at 8:06 ↗
// Object tracking

Task {
    do {
        let url = URL(fileURLWithPath: "/path/to/globe.referenceobject")
        let referenceObject = try await ReferenceObject(from: url)
        let objectTracking = ObjectTrackingProvider(referenceObjects: [referenceObject])
    } catch {
        // Handle reference object loading error.
    }
    ...
}
Run ARKitSession with ObjectTracking provider swift · at 8:27 ↗
let session = ARKitSession()

Task {
    do {
        try await session.run([objectTracking])
    } catch {
        // Handle session run error.
    }
    
    for await event in session.events {
        switch event {
        case .dataProviderStateChanged(_, newState: let newState, _):
            if newState == .running {
                // Ready to start processing anchor updates.
            }
        ...
        }
    }
}
ObjectAnchor swift · at 8:43 ↗
// ObjectAnchor

@available(visionOS, introduced: 2.0)
public struct ObjectAnchor: TrackableAnchor, Sendable, Equatable {

    /// An axis-aligned bounding box.
    public struct AxisAlignedBoundingBox: Sendable, Equatable {
        ...
    }

    /// The bounding box of this anchor.
    public var boundingBox: AxisAlignedBoundingBox { get }

    /// The reference object which this anchor corresponds to.
    public var referenceObject: ReferenceObject { get }
}
World Tracking - reacting to changes in lighting conditions swift · at 11:03 ↗
struct WellPreparedView: View {
    @Environment(\.worldTrackingLimitations) var worldTrackingLimitations
    
    var body: some View {
        ...
 
        .onChange(of: worldTrackingLimitations) {
            if worldTrackingLimitations.contains(.translation) {
                // Rearrange content when anchored positions are unavailable.
            }
        }
    }
}
Hands prediction swift · at 12:51 ↗
// Hands prediction

func submitFrame(_ frame: LayerRenderer.Frame) {
    ...

    guard let drawable = frame.queryDrawable() else { return }

    // Get the trackable anchor time to target.
    let trackableAnchorTime = drawable.frameTiming.trackableAnchorTime

    // Convert the timestamp into units of seconds.
let anchorPredictionTime = LayerRenderer.Clock.Instant.epoch.duration(to:
    trackableAnchorTime).timeInterval  

    // Predict hand anchors for the time that provides best content registration.
    let (leftHand, rightHand) = handTracking.handAnchors(at: anchorPredictionTime)
    
    ...
}

Resources