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 ↗Code shown on screen · 13 snippets
Instantiating ObjectCaptureSession
import RealityKit
import SwiftUI
var session = ObjectCaptureSession() Starting the session
var configuration = ObjectCaptureSession.Configuration()
configuration.checkpointDirectory = getDocumentsDir().appendingPathComponent("Snapshots/")
session.start(imagesDirectory: getDocumentsDir().appendingPathComponent("Images/"),
configuration: configuration) Creating ObjectCaptureView
import RealityKit
import SwiftUI
struct CapturePrimaryView: View {
var body: some View {
ZStack {
ObjectCaptureView(session: session)
}
}
} Transition to detecting state
var body: some View {
ZStack {
ObjectCaptureView(session: session)
if case .ready = session.state {
CreateButton(label: "Continue") {
session.startDetecting()
}
}
}
} Showing ObjectCaptureView
var body: some View {
ZStack {
ObjectCaptureView(session: session)
}
} Transition to capturing state
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
var body: some View {
ZStack {
ObjectCaptureView(session: session)
}
} Completed scan pass
var body: some View {
if session.userCompletedScanPass {
VStack {
}
} else {
ZStack {
ObjectCaptureView(session: session)
}
}
} Transition to finishing state
var body: some View {
if session.userCompletedScanPass {
VStack {
CreateButton(label: "Finish") {
session.finish()
}
}
} else {
ZStack {
ObjectCaptureView(session: session)
}
}
} Point cloud view
var body: some View {
if session.userCompletedScanPass {
VStack {
ObjectCapturePointCloudView(session: session)
CreateButton(label: "Finish") {
session.finish()
}
}
} else {
ZStack {
ObjectCaptureView(session: session)
}
}
} Reconstruction API
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
// Capturing for Mac
var configuration = ObjectCaptureSession.Configuration()
configuration.isOverCaptureEnabled = true
session.start(imagesDirectory: getDocumentsDir().appendingPathComponent("Images/"),
configuration: configuration) Pose output
// 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
Related sessions
-
21 min