本記事ではApple Vision Proの位置と向きを取得する方法を紹介します。
デモ
方法
ARKitSessionをWorldTrackingProvider
で開始し、そのqueryDeviceAnchor(atTimestamp:)
メソッドを呼び出すことで、DeviceAnchor
を作成します。
DeviceAnchor
にはApple Vision Proのデバイスの位置と向きの情報が含まれています。
originFromAnchorTransform
を使用することで、デバイスから見た空間における平面の位置と方向を取得することができます。
実装
ImmersiveViewModel
@MainActor
final class ImmersiveViewModel: ObservableObject {
let session = ARKitSession()
let worldInfo = WorldTrackingProvider()
func run() async {
do {
try await session.run([worldInfo])
await handleAnchorUpdates()
} catch {
assertionFailure("Failed to run session: \(error)")
}
}
func handleAnchorUpdates() async {
for await update in worldInfo.anchorUpdates {
switch update.event {
case .added, .updated:
print("Anchor position updated.")
case .removed:
print("Anchor position now unknown.")
}
}
}
func getTransform() async -> simd_float4x4? {
if let anchor = worldInfo.queryDeviceAnchor(atTimestamp: CACurrentMediaTime()) {
return anchor.originFromAnchorTransform
}
return nil
}
}
WorldTracking用に設定されたARKitSessionを使用し、DeviceAnchorのUpdate情報の受信を開始します。
ImmersiveView
struct ImmersiveView: View {
@StateObject var vm: ImmersiveViewModel = ImmersiveViewModel()
@State var timer = Timer.publish(every: 0.02, on: .main, in: .common).autoconnect()
var body: some View {
RealityView { content in
// Add the initial RealityKit content
if let scene = try? await Entity(named: "Immersive", in: realityKitContentBundle) {
content.add(scene)
}
}
.task() {
await vm.run()
}
.onReceive(timer) { _ in
Task {
let transform = await vm.getTransform()
let position = SIMD3<Float>(transform!.columns.3.x, transform!.columns.3.y, transform!.columns.3.z)
print("x: \(position.x), y: \(position.y), z: \(position.z)")
}
}
}
}
Apple Vision Proデバイスの位置と向きが0.02秒ごとに取得され、コンソールに表示されます。これにより、ARコンテンツをデバイスの動きに合わせて更新することが可能になります。
(※技適特例届け出済み)
参考資料