ストリーミングはほとんどのブラウザと
Developerアプリで視聴できます。
-
RoomPlanによるパラメトリックな3Dルームスキャンの作成
RoomPlanを使用すると、Appで簡単にパラメトリックな3Dルームスキャンを作成できるようになります。このAPIを使って、部屋のスキャン体験を簡単に実現する方法をご確認ください。このAPIを組み込む方法、3Dのパラメトリックな出力、Appで優れた結果を得るためのベストプラクティスについても紹介します。
リソース
関連ビデオ
Tech Talks
WWDC23
WWDC22
-
ダウンロード
♪♪ こんにちは Prototypingチームの Praveenです こんにちは Video Engineeringチームの Kaiです この数年間 Appleは パワフルな新しい方法で みなさんの世界をAppで 表現することを可能にしました 昨年はObject Captureを導入し 実世界の写真を取り込み Photogrammetry APIを 使って Appで使える3Dモデルに 変換できるようになりました Object Captureの前に Scene Reconstruction APIを リリース これを利用して 空間の幾何学的 構造の理解と Appでの 全く新しい拡張現実の ユースケースを 可能にしました 今年はRoomPlanという 全く新しいフレームワーク を発表できることに興奮してます RoomPlanは LiDAR対応の iPhoneかiPadを使い 部屋をスキャンできます Appで使えるパラメトリックな 部屋の3Dモデルと 部屋のオブジェクトが 生成されます RoomPlanのスキャン体験が どのようなものになるのか 確認してみましょう RoomPlanは ARKitを利用した 高度な機械学習 アルゴリズムにより 壁 窓 開口部 ドアや 暖炉 ソファ テーブル キャビネットなどといった部屋の中の オブジェクトを検出します RealityKitを使って スキャンの進行状況を レンダリングする RoomCaptureView APIを 使うと スキャン体験を簡単に Appに組み込めます スキャンが終了すると RoomCaptureViewが ポストプロセスの結果を提供し ユースケースに適合させる形で 利用することができます 機械学習や分析といった 複雑な実装なしで 全く新しい方法で 部屋とインタラクション することが可能になりました 例えばインテリア デザインのAppであれば 壁の色の変更を プレビューし 必要な塗料の量を 正確に計算できます 建築Appの場合は 部屋のレイアウト変更の プレビューや編集が リアルタイムで可能に 不動産Appの場合は 業者が間取りをキャプチャし その3Dモデルを提供できます EコマースAppの場合は 部屋で製品を視覚化し 顧客を引き付けることができます これらはRoomPlanが 可能にする Appのほんの一例です RoomPlanの組み込みの 簡単さに驚くかもしれません 見てみましょう RoomPlanの 使用方法は2つあります 1つ目はシームレスに 取り込みができ すぐ使えるスキャン機能 2つ目はユースケースに 最適化した形で ライブでパラメトリック データを 使えるようにする データAPIです それぞれのAPIで 最適なスキャン結果のための ベストプラクティスの適用を お薦めしています これについてはプレゼンの最後に 説明します まず Appに組み込み可能な 新しい RoomCaptureView APIを使った スキャン体験について 説明します RoomCaptureViewは Appに配置できる UIViewのサブクラスです ワールドスペースのスキャンの フィードバックの表示 リアルタイムでの 部屋のモデルの生成 ユーザーガイダンスなどを 処理します RoomCaptureViewベースの スキャンで 表示されるデザイン要素を 詳しく見ましょう RoomCaptureViewでは 検出された壁 窓 開口部 ドアや 部屋のオブジェクトが リアルタイムに 線のアニメーションで囲われます インタラクティブな 3Dモデルは リアルタイムで生成され スキャンの進捗状況が すぐ把握できます テキストによる コーチングで 最適なスキャン結果を 導き出します RoomCaptureViewを 使うための 4つの簡単な手順を 確認してみましょう まずRoomCaptureView の参照を ViewControllerで作成 次に RoomCaptureSession configurationオブジェクトへの 参照を作成 スキャンのセッションを 開始すべく captureSessionの run関数に configurationを渡します 最後にAppで captureSessionに スキャンの停止を指示します オプションで Appを RoomCaptureViewDelegateに 準拠させることができます ポストプロセスの結果や プレゼンテーションを オプトアウトしたり 利用可能になった時点で ポストプロセスの結果を 処理することができます 結果として得られる CapturedRoomデータ構造体を export関数で USDZとして エクスポートできます ご覧いただいたように RoomPlanをAppに 組み込むのは簡単です APIを使ってみなさんが 何を生み出されるか楽しみです それでは 同僚のKaiが RoomCaptureSessionと RoomPlanのData APIについて 説明します どうもPraveen このセクションでは スキャン中に 基盤となっている データ構造へのアクセスと スキャン体験のカスタム ビジュアライゼーションの構築に 有益なデータAPIついて 説明します 基本的なワークフローは スキャン 処理 エクスポートの 3つで構成されます まずスキャンのための キャプチャセッションの設定・開始 キャプチャプロセスの 表示とモニタリング方法の 基本について説明します 次にスキャンデータの 処理過程と プレゼンテーション用の最終モデルが どう渡されるかを確認します 最後にUSDワークフローでも 使用できる USDファイル出力を生成して エクスポートする方法の説明 ではスキャンについて 説明します RoomCaptureSession API でセッションをセットアップし スキャンを継続しながら 進行状況を表示します コードでお見せしましょう 簡単なRealityKit Appの例です まずRoomPlanを Swiftプロジェクトにインポート ViewControllerで RoomCaptureSession インスタンスを初期化し 結果のビジュアライズのための カスタム型を持たせます RoomCaptureSessionには 基盤となっている AR Sessionのハンドルがあるので 平面やオブジェクトの 境界ボックス描画ができます RoomCaptureSessionは デリゲートパターンを採用しており ViewControllerクラスで ViewController 自体を captureSessionの デリゲートとして 割り当てられます ViewControlleは RoomCaptureSessionから リアルタイム更新を取得できます 更新にはキャプチャ中の ガイドのための 3Dモデルやインストラクションが 含まれています 更新の取得には ViewControllerが RoomCaptureSessionDelegate プロトコルに準拠し 2つのメソッドの実装が 必要になります まず1つ目は captureSession(_session: didUpdate room:) メソッドで CapturedRoomデータ 構造体を取得します 自身のビジュアライザで これを使用して 3DモデルのAR Viewを更新し リアルタイムの フィードバックを提供できます CapturedRoom構造体 については 後ほど詳しく説明します このメソッドは CapturedRoomに対する アップデートが 検出された際に呼ばれます 2つ目は captureSession(_session: didProvide instruction:)です リアルタイムの フィードバックを含む インストラクションの 構造体を提供します これを利用して ビジュアライザで ユーザーをガイドします このAPIが提供する インストラクションを 確認してみましょう インストラクションには オブジェクトまでの距離 スキャン速度 部屋の照明の調整 テクスチャの多い場所への フォーカスなどが含まれます これらはスキャン中に 提供されるので リアルタイムなフィードバックとして ガイドすることができます 次はプロセスのパートに 進みます RoomBuilderクラスで スキャンデータを処理し 3Dモデルの生成します キャプチャデータを 処理するためには まずRoomBuilder インスタンスを初期化します キャプチャプロセス後に センサデータを受け取るためには captureSession(_session:didEndWith data: error:) の実装が必要です stop () 関数やエラーによって RoomCaptureSessionが 停止された場合 この関数が呼ばれ CaptureRoomDataオブジェクトと オプションのエラーが 返されます 最後にキャプチャデータを 処理する場合は roomBuilderの async roomModel (from:)を awaitキーワードとともに 呼びます スキャンデータを処理し 最終的な3Dモデルの構築 非同期で実行します ここでは昨年のWWDCで 紹介した Swiftのasync/awaitを 利用しています 数秒以内に みなさんのAppに 最終的なプレゼンテーションモデルが できあがります ではCapturedRoomの データ構造の詳細と App用にエクスポート する方法を説明します トップレベルには SurfaceとObjectで 構成されたCapturedRoomが サーフェスにはカーブを表す 固有の属性が 半径 開始角度 終了角度 などです サーフェスの 4つの異なるエッジ; 壁 開口部 窓 ドアといった 建築のカテゴリが含まれます オブジェクトにはテーブル ベッドやソファなどの 家具のカテゴリが サーフェスとオブジェクト には 共通属性があり; 寸法やスキャンされた 3つのレベルの信頼度 3D変換行列 ユニークな識別子などです コードでの表現を 見てみましょう CapturedRoom構造体は 部屋の要素の パラメトリックな表現 となっています 壁 開口部 ドア 窓や 部屋のオブジェクトなど 5つのプロパティが 含まれます 最初の4つの要素は 2Dの平面的な建築構造が Surface構造体として 表されます 右側には先ほど説明した さまざまなプロパティが あります 最後のプロパティは部屋内の 3 Dオブジェクトの配列で オブジェクトは 立方体として表されます 右側にオブジェクトの プロパティを表示しています こちらがRoomPlanがサポートする オブジェクトの一覧です これにはソファ テーブル 椅子など 一般的な多種多様の 家具が含まれます 最後に エクスポート機能により CapturedRoomを USDまたは USDZデータに エクスポートできます Cinema 4Dで USD出力を開き 部屋の階層的なデータ構造 各部屋の要素や オブジェクトの 寸法と位置を 参照したり編集したりする ことができる例です 既存のUSDやUSDZの ワークフローを活用し 不動産 Eコマース インテリアなど さまざまなAppに キャプチャした部屋の レンダ情報を追加することも できます スキャン体験と RoomPlan APIの 説明をしました RoomPlanを 使いこなすベストプラクティス について紹介します ここでは 適切なスキャンを 可能にするための 推奨条件として 部屋を選択する際の 部屋の特徴など 注意する点を 説明します RoomPlan APIは 一般家庭の建築構造と オブジェクトを サポートします 1部屋を対象すると ベストな動作となります 最大サイズは 30ft x 30ft まで または約 9m x 9m です 照明はAPIにとって重要で クリアなビデオストリームと 優れた ARトラッキング性能に繋がります 最低50ルクス以上が 推奨されており 夜間のリビングルーム くらいの明るさとなります RoomPlan APIは LiDAR対応のiPhoneと iPad Pro全モデルに対応しています APIを利用する上で いくつか特別な条件が あります フルに高さのあるミラーや ガラスは LiDARセンサの出力の観点から 課題となります 天井が高い場合も LiDARセンサの レンジを超えてしまう ことがあります 非常に暗い表面はスキャンが 難しくなる場合があります 最良の結果を得るには 考慮事項があります まず高い精度が要求される Appでは スキャン前の 部屋の準備で 品質を高めること できます 日中のスキャンは カーテンを開けると 自然光が入り 窓を遮るものを 軽減することができます ドアを閉めると 部屋の外の 不要な部分を スキャンせずにすみます また APIで優れたスキャンを 行うためには 良いスキャンモーションが 重要です フィードバックの提供のために テクスチャ 距離 速度 照明条件について スキャン中 ユーザーに通知します 気をつけることは バッテリーと発熱です RoomPlan APIで 多くの最適化をし 優れたスキャン体験を実現 していますが とはいえ繰り返しスキャンや 5分以上の長時間の 使用は避けましょう 疲労の原因のほか バッテリーの消耗と 発熱問題で Appのユーザー体験に 影響を与える可能性が 今回は盛りだくさんでした 最新のRoomPlan APIを 紹介しました 部屋を撮影するための 直感的なスキャン体験 環境を理解する強力な 機械学習モデル Appに簡単に 組み込めるよう パラメトリックな USD出力形式の提供 新しいRoomPlan体験を デザインし実装するための ガイダンスは 関連セッションを チェックしてください RoomPlanをお試しください 新APIでみなさんが 何を作られるか楽しみです ありがとうございました ♪♪
-
-
4:36 - RoomCaptureView API - Scan & Process
// RoomCaptureView API - Scan & Process import UIKit import RoomPlan class RoomCaptureViewController: UIViewController { var roomCaptureView: RoomCaptureView var captureSessionConfig: RoomCaptureSession.Configuration private func startSession() { roomCaptureView?.captureSession.run(configuration: captureSessionConfig) } private func stopSession() { roomCaptureView?.captureSession.stop() } }
-
5:00 - RoomCaptureView API - Export
// RoomCaptureView API - Export import UIKit import RoomPlan class RoomCaptureViewController: UIViewController { … func captureView(shouldPresent roomDataForProcessing: CapturedRoomData, error: Error?) -> Bool { // Optionally opt out of post processed scan results. return false } func captureView(didPresent processedResult: CapturedRoom, error: Error?) { // Handle final, post processed results and optional error. // Export processedResults … try processedResult.export(to: destinationURL) … } }
-
6:50 - RoomCaptureSession - setup previewVisualizer
import UIKit import RealityKit import RoomPlan import ARKit class ViewController: UIViewController { @IBOutlet weak var arView: ARView! var previewVisualizer: Visualizer! lazy var captureSession: RoomCaptureSession = { let captureSession = RoomCaptureSession() arView.session = captureSession.arSession return captureSession }() override func viewDidLoad() { super.viewDidLoad() captureSession.delegate = self // set up previewVisualizer } }
-
7:40 - RoomCaptureSession - live results and user instructions
// Getting live results and user instructions extension ViewController: RoomCaptureSessionDelegate { func captureSession(_ session: RoomCaptureSession, didUpdate room: CapturedRoom) { previewVisualizer.update(model: room) } func captureSession(_ session: RoomCaptureSession, didProvide instruction: Instruction) { previewVisualizer.provide(instruction) } }
-
9:12 - Setup RoomBuilder
// RoomBuilder import UIKit import RealityKit import RoomPlan import ARKit class ViewController: UIViewController { @IBOutlet weak var arView: ARView! var previewVisualizer: Visualizer! // set up RoomBuilder var roomBuilder = RoomBuilder(options: [.beautifyObjects]) }
-
9:30 - RoomBuilder - generate final 3D CapturedRoom
// RoomBuilder with the latest CapturedRoomData to generate final 3D CapturedRoom extension ViewController: RoomCaptureSessionDelegate { func captureSession(_ session: RoomCaptureSession, didEndWith data: CapturedRoomData, error: Error?) { if let error = error { print("Error: \(error)") } Task { let finalRoom = try! await roomBuilder.capturedRoom(from: data) previewVisualizer.update(model: finalRoom) } } }
-
11:20 - CapturedRoom and export
// CapturedRoom and export public struct CapturedRoom: Codable, Sendable { public let walls: [Surface] public let doors: [Surface] public let windows: [Surface] public let openings: [Surface] public let objects: [Object] public func export(to url: URL) throws // Surface definitions ... // Object definitions ... }
-
-
特定のトピックをお探しの場合は、上にトピックを入力すると、関連するトピックにすばやく移動できます。
クエリの送信中にエラーが発生しました。インターネット接続を確認して、もう一度お試しください。