WWDC Quick Look 💓 By SwiftGGTeam
Evolve your ARKit app for spatial experiences

Evolve your ARKit app for spatial experiences

元の動画を見る

ハイライト

visionOS では ARKit と RealityKit が OS に深く統合され、ワールドトラッキングとシーン理解がシステムサービスになりました。アプリはカメラパススルー、ハンドマッティング、World Map の自動永続化を無料で利用できます。iOS AR アプリの移行には、新しい空間表示方式、ARView を置き換える RealityView、Configuration から Data Provider への API 変更の理解が必要です。

主要内容

ARKit 3つの核心概念の進化

(00:25) 2017年に iOS で導入された ARKit は、3つの核心概念を定義しました:

  • World Tracking: デバイス位置の6自由度トラッキングで、仮想コンテンツを現実世界に固定します
  • Scene Understanding: 周囲環境のセマンティック情報を提供し、コンテンツの賢い配置と現実との相互作用を可能にします
  • Rendering Registration: カメラ変換と内部パラメータで仮想コンテンツを正しく登録・合成します

visionOS ではこれらの概念はすべて維持されますが、実装方法が根本的に変わりました。

システムレベルのサービス化

(01:34) ARKit のトラッキングとシーン理解はシステムサービスとして動作し、ウィンドウ配置から空間オーディオまであらゆる機能を支えます。システムが以前はアプリの責任だった処理を担います:

  • カメラパススルーは組み込み済みで、アプリは無料で利用できます
  • ハンドマッティングは組み込み済みで、アプリは無料で利用できます
  • World Map はシステムサービスが継続的に永続化し、アプリが自分で処理する必要はありません

これにより開発者はコンテンツと体験の構築に集中できます。

3つの空間表示方式

(04:25)

Shared Space: アプリが並列実行され、Mac デスクトップのように動作します。アプリは1つ以上のウィンドウを開くか、3D Volume を作成できます。コンテンツはそれぞれの境界内に留まり、他のアプリと空間を共有します。

Volume: Shared Space で 3D コンテンツを表示するコンテナです。例えば、1つのウィンドウにボードゲームのリスト、別のウィンドウにルールを表示し、選択したゲームを独立した Volume で開きます。

Full Space: アプリが空間全体を占有し、そのアプリのウィンドウ、Volume、3D オブジェクトのみが表示されます。Full Space では AnchorEntity で机や床などの表面にコンテンツを固定でき、ARKit データにアクセスできます。

RealityView: SwiftUI と RealityKit の橋渡し

(08:44) RealityView は iOS の ARView を置き換える新しい SwiftUI ビューです。2D と 3D の要素を同時に収容し、ユーザーがシステムジェスチャでエンティティと対話できます。

RealityView と ARView の比較:

機能ARView (iOS)RealityView (visionOS)
コンテナタイプSceneContent
ジェスチャサポートタッチジェスチャ空間ジェスチャ(手を伸ばして選択/ドラッグ)
エンティティのアンカーARSession + 権限が必要システムサービスでサポート、権限不要
基盤トラッキングARSessionシステムサービス

(10:09) RealityKit の Entity Component System は引き続き適用されます: エンティティは 3D コンテンツのコンテナ、コンポーネントは外観と動作を定義し(ModelComponent、CollisionComponent など)、システムは必要なコンポーネントを持つエンティティを操作します。

プライバシーに配慮した AnchorEntity 設計

(14:19) visionOS では、ユーザー権限をリクエストせずに AnchorEntity を使用できます。システムがターゲット(例: 机)を見つけて自動的にコンテンツをアンカーしますが、基盤の変換データはアプリに開示しません。

新しい AnchorEntity ターゲットには手が含まれ、手のひらや手首にコンテンツをアンカーでき、コンテンツは手の動きに追従します。

異なる AnchorEntity の子エンティティは互いに見えません。それぞれ異なる座標空間に存在するためです。

空間コンピューティングにおけるレイキャスト

(17:01) iOS ではレイキャストが 2D 入力を 3D 位置に変換します。visionOS ではユーザーが直接手でコンテンツと対話できますが、レイキャストは依然として有用です。腕の届かない物体に届くことができます。

2つのレイキャスト方式:

システムジェスチャのレイキャスト: エンティティに CollisionComponent と InputTargetComponent を追加し、RealityView に SpatialTapGesture を追加します。ユーザーがエンティティを見つめてタップすると、ワールド空間の位置が返されます。

ハンドデータのレイキャスト: ARKit のハンドアンカーで指関節情報を取得し、レイの起点と方向を構築して、シーン内のエンティティに対してレイキャストを実行します。

ARKit API の再設計: Data Provider パターン

(22:08) iOS の ARKit は Configuration パターンを使用します:

// iOS 方式(非推奨)
let configuration = ARWorldTrackingConfiguration()
configuration.sceneReconstruction = .mesh
configuration.planeDetection = [.horizontal, .vertical]
let session = ARSession()
session.run(configuration)

visionOS では Data Provider パターンを使用します:

// visionOS method
let sceneReconstruction = SceneReconstructionProvider(modes: [.classification])
let planeDetection = PlaneDetectionProvider(alignments: [.horizontal, .vertical])
let session = ARKitSession()
try await session.run([sceneReconstruction, planeDetection])

キーポイント:

  • 各機能に独立した Data Provider があります
  • ハンドトラッキングにも独立した Provider があります
  • Provider 初期化時にパラメータを設定します
  • ARKitSession.run() は Provider の配列を受け取ります

アンカー更新の非同期配信

(23:50) iOS では単一のデリゲートが ARFrame に集約されたアンカー更新を受け取ります。visionOS では各 Data Provider が独立して非同期にアンカー更新を配信します:

  • SceneReconstructionProviderMeshAnchor を配信します
  • PlaneDetectionProviderPlaneAnchor を配信します
  • 型の区別は不要です
  • アンカー更新は他の Provider から切り離され、レイテンシが低くなります
  • システムが表示を自動処理するため ARFrame は提供されません

World Anchor の永続化

(25:12) iOS ではアプリが World Map とアンカーの永続化を自分で処理する必要があります: リクエスト、保存、読み込み、再ローカライズの待機。

visionOS ではシステムがバックグラウンドで World Map を継続的に永続化し、自動的に読み込み、解放、作成、再ローカライズします。アプリは World Anchor 自体に集中すれば十分です:

// WorldTrackingProvider で WorldAnchor を追加
let worldTracking = WorldTrackingProvider()
try await session.run([worldTracking])

let anchor = WorldAnchor(originFromAnchorTransform: placementTransform)
try await worldTracking.add(anchor)

システムがこれらのアンカーを自動保存します。デバイスが同じ環境に戻ると、アプリは以前に永続化されたアンカー更新を自動的に受け取ります。

詳細

ARKit Mesh Anchor から衝突エンティティを構築

(18:17) シーン再構築データは mesh chunk として配信されます。各 chunk にエンティティを作成します:

// mesh chunk を表すエンティティを作成
let entity = Entity()

// mesh anchor の変換でエンティティを配置
entity.transform = Transform(matrix: meshAnchor.originFromAnchorTransform)

// mesh anchor から衝突形状を生成
let shape = try await ShapeResource.generateStaticMesh(from: meshAnchor)
entity.components[CollisionComponent.self] = CollisionComponent(shapes: [shape])

// ジェスチャ操作のために InputTargetComponent を追加
entity.components[InputTargetComponent.self] = InputTargetComponent()

キーポイント:

  • originFromAnchorTransform でエンティティを Full Space に正しく配置します
  • ShapeResource.generateStaticMesh で mesh anchor から衝突形状を生成します
  • CollisionComponent でエンティティのヒットテストを有効にします
  • InputTargetComponent でエンティティがシステムジェスチャを受信できます
  • シーン再構築データは更新されるため、変更を監視してエンティティを更新する必要があります

ハンドデータでレイキャストを実行

// 指関節位置からレイを構築
let handAnchor = latestHandAnchors.left

if let indexTip = handAnchor.handSkeleton?.joint(.indexTip),
   let indexIntermediate = handAnchor.handSkeleton?.joint(.indexIntermediate) {
    let origin = indexTip.anchorFromJointTransform.columns.3.xyz
    let direction = normalize(
        indexIntermediate.anchorFromJointTransform.columns.3.xyz - origin
    )
    
    // レイキャストを実行
    let hits = content.entities(
        raycastingFrom: origin,
        in: direction,
        length: 10.0
    )
    
    if let hit = hits.first {
        // ヒット位置に WorldAnchor を配置
        let anchor = WorldAnchor(originFromAnchorTransform: hit.position)
        try await worldTracking.add(anchor)
        
        // エンティティを作成して変換を設定
        let modelEntity = try Entity.load(named: "ship")
        modelEntity.transform = Transform(matrix: anchor.originFromAnchorTransform)
        content.add(modelEntity)
    }
}

キーポイント:

  • 指関節からレイの起点と方向を取得します
  • raycastingFrom:in:length: でシーンエンティティに対してレイキャストを実行します
  • CollisionCastHit はヒットエンティティ、位置、表面法線を提供します
  • WorldAnchor でコンテンツを現実世界に固定し続けます
  • ARKit が WorldAnchor を更新したら、エンティティの変換を同期します

重要ポイント

1. iOS AR 家具配置アプリを visionOS に移行

  • やること: 既存の AR 家具プレビューアプリを visionOS に持ち込み、Shared Space で家具を閲覧し、Full Space で実際の部屋に配置できるようにする
  • 価値がある理由: システムが World Map の永続化を無料で処理し、AnchorEntity は権限なしで机にアンカーできます。ユーザーは直接手で家具を掴んで配置できます
  • 始め方: ARView を RealityView に置き換え、Shared Space で Volume に家具モデルを表示し、Full Space に切り替えた後に AnchorEntity または ARKit PlaneAnchor で配置します

2. ジェスチャ駆動の 3D コンテンツ作成ツールを構築

  • やること: ユーザーがジェスチャで実環境に 3D モデルを配置、スケール、回転できるようにする
  • 価値がある理由: ARKit ハンドトラッキングは完全な骨格データを提供し、RealityKit の衝突システムはレイキャスト操作をサポートします。システムジェスチャでユーザーが自然に手を伸ばして物体を選択できます
  • 始め方: Full Space で ARKitSession を実行し、HandTrackingProvider を購読してハンドデータを取得し、指関節位置からレイを構築して mesh エンティティにレイキャストします

3. 永続的な空間メモアプリを作成

  • やること: ユーザーが実環境の特定の位置に仮想メモやマーカーを残せるようにする
  • 価値がある理由: WorldAnchor は自動的に永続化され、ユーザーが同じ場所に戻るとメモが自動的に表示されます。システムがすべての World Map 管理を処理し、アプリはアンカー自体に集中すれば十分です
  • 始め方: WorldTrackingProvider で WorldAnchor を追加し、アンカーの identifier でメモコンテンツを関連付け、アンカー更新を監視して対応するメモを読み込み/表示します

4. 協調型空間デザインレビューツールを開発

  • やること: デザインチームが 3D 空間で建築や製品デザインを共同レビューできるようにする
  • 価値がある理由: Shared Space では複数のアプリが並列実行でき、チームメンバーがデザインドキュメントと 3D モデルを同時に閲覧できます。Full Space モードではデザインを実際の机に固定して 1:1 スケールでレビューできます
  • 始め方: Shared Space でウィンドウにデザインドキュメントを表示し、Volume で 3D モデルを表示します。Full Space に切り替えた後、AnchorEntity でモデルを机にアンカーします

関連セッション

コメント

GitHub Issues · utterances