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

2023 Spatial Computing

WWDC23 · 20 min · Spatial Computing

Meet Object Capture for iOS

Discover how you can offer an end-to-end Object Capture experience directly in your iOS apps to help people turn their objects into ready-to-use 3D models. Learn how you can create a fully automated Object Capture scan flow with our sample app and how you can assist people in automatically capturing the best content for their model. We’ll also discuss LiDAR data and provide best practices for scanning objects.

Watch at developer.apple.com ↗

Transcript all transcripts

Code shown on screen · 13 snippets

Instantiating ObjectCaptureSession swift · at 10:03 ↗
import RealityKit
import SwiftUI 

var session = ObjectCaptureSession()
Starting the session swift · at 10:25 ↗
var configuration = ObjectCaptureSession.Configuration()
configuration.checkpointDirectory = getDocumentsDir().appendingPathComponent("Snapshots/")

session.start(imagesDirectory: getDocumentsDir().appendingPathComponent("Images/"),
              configuration: configuration)
Creating ObjectCaptureView swift · at 10:50 ↗
import RealityKit
import SwiftUI

struct CapturePrimaryView: View {
    var body: some View {
        ZStack {
            ObjectCaptureView(session: session)
        }
    }
}
Transition to detecting state swift · at 11:20 ↗
var body: some View {
    ZStack {
        ObjectCaptureView(session: session)
        if case .ready = session.state {
            CreateButton(label: "Continue") { 
                session.startDetecting() 
            }
        }
    }
}
Showing ObjectCaptureView swift · at 11:36 ↗
var body: some View {
    ZStack {
        ObjectCaptureView(session: session)
    }
}
Transition to capturing state swift · at 12:04 ↗
var body: some View {
    ZStack {
        ObjectCaptureView(session: session)
        if case .ready = session.state {
            CreateButton(label: "Continue") { 
                session.startDetecting()
            }
        } else if case .detecting = session.state {
            CreateButton(label: "Start Capture") { 
                session.startCapturing()
            }
        }
    }
}
Showing ObjectCaptureView swift · at 12:27 ↗
var body: some View {
    ZStack {
        ObjectCaptureView(session: session)
    }
}
Completed scan pass swift · at 12:50 ↗
var body: some View {
    if session.userCompletedScanPass {
        VStack {
        }
    } else {
        ZStack {
            ObjectCaptureView(session: session)
        }
    }
}
Transition to finishing state swift · at 14:03 ↗
var body: some View {
    if session.userCompletedScanPass {
        VStack {
            CreateButton(label: "Finish") {
                session.finish() 
            }
        }
   } else {
        ZStack {
            ObjectCaptureView(session: session)
        }
    }
}
Point cloud view swift · at 15:00 ↗
var body: some View {
    if session.userCompletedScanPass {
        VStack {
            ObjectCapturePointCloudView(session: session)
            CreateButton(label: "Finish") {
                session.finish() 
            }
        }
    } else {    
        ZStack {
            ObjectCaptureView(session: session)
        }
    }
}
Reconstruction API swift · at 15:50 ↗
var body: some View {
    ReconstructionProgressView()
        .task {
            var configuration = PhotogrammetrySession.Configuration()
            configuration.checkpointDirectory = getDocumentsDir()
                .appendingPathComponent("Snapshots/")
            let session = try PhotogrammetrySession(
                input: getDocumentsDir().appendingPathComponent("Images/"),
                configuration: configuration)
            try session.process(requests: [ 
                .modelFile(url: getDocumentsDir().appendingPathComponent("model.usdz")) 
            ])
            for try await output in session.outputs {
                switch output {
                    case .processingComplete:
                        handleComplete()
                        // Handle other Output messages here.
                }}}}
Capturing for Mac swift · at 17:02 ↗
// Capturing for Mac

var configuration = ObjectCaptureSession.Configuration()
configuration.isOverCaptureEnabled = true

session.start(imagesDirectory: getDocumentsDir().appendingPathComponent("Images/"),
              configuration: configuration)
Pose output swift · at 18:40 ↗
// Pose output

try session.process(requests: [ 
    .poses 
    .modelFile(url: modelURL),
])
for try await output in session.outputs {
    switch output {
    case .poses(let poses):
        handlePoses(poses)
    case .processingComplete:
        handleComplete()
    }
}

Resources