Edited at

USDZ形式の3DモデルをModel I/Oで読み込みSceneKitで利用する

More than 1 year has passed since last update.

WWDC18で発表されたARコンテンツの新フォーマット "USDZ" ですが、同WWDCでのセッション「Integrating Apps and Content with AR Quick Look」ではQLPreviewControllerやSafariでプレビューするためのHTMLの解説はあれど、ARKit・SceneKitで利用するための実装方法については提示されていませんでした1

しかし、「ARKitアプリケーションの実装をしなくてもAR体験を提供できるフォーマット」という点がUSDZの最もインパクトがある点だとしても、それを含めて「ユニバーサル」2である点がUSDZという新フォーマットの売りであるはずで、ARKitでの利用方法(=SceneKitでの利用方法)について明示されないのは片手落ち感を感じてしまいました。「ブラウザやプレビューでAR体験を提供するための『専用』フォーマット」ではないはずで。

おそらく、USDZはSceneKitでの利用だけ見るとUSDと同様で、USD自体はModel I/Oでの読み込みがiOS 10で既にサポートされていたので、そこは自明(新しいフィーチャーではない)として解説しなかったのでしょう。

とはいえ私のように「で、USDZってARKit(SceneKit)ではどう利用するの」とググった方(これからググる方)は多いと思われるので、ここに実装を示しておきます。


実装


.usdzファイルからMDLAssetを初期化する

読み込みにはModel I/Oフレームワークを利用します。アプリケーションバンドル内の.usdzファイルのURLをMDLAssetのイニシャライザに渡して初期化するだけです。

guard let url = Bundle.main.url(forResource: name, withExtension: "usdz") else { fatalError() }

let mdlAsset = MDLAsset(url: url)

ちなみに、MDLAssetがサポートしている(ロード可能な)ファイル形式は、MDLAssetcanImportFileExtension(_:)から調べることができます。同メソッドのリファレンスにも、サポートしているファイル形式が載っています。3


  • Alembic


    • .abc



  • Universal Scene Description



    • .usd, .usda, .usdc



  • Universal Scene Description (Mobile)


    • .usdz



  • Polygon


    • .ply



  • Wavefront Object


    • .obj



  • Standard Tessellation Language


    • .stl




MDLAssetからSCNSceneを初期化する

SCNSceneのリファレンスを見ると、次のようなイニシャライザがあります。

convenience init(mdlAsset: MDLAsset)

しかし、このイニシャライザは、import ARKitimport SceneKitimport ModelIOしていても使えません。次のようにSceneKit.ModelIOをインポートする必要があります。

import SceneKit.ModelIO

先ほど作成したMDLAssetオブジェクトをイニシャライザに渡し、SCNSceneを初期化します。

let scene = SCNScene(mdlAsset: mdlAsset)

あとは通常通り(.scnファイル等からSCNSceneを初期化した場合と同様)のSceneKitの実装になります。


サンプルコード

「ARKit-Sampler」にAppleの公式配布usdzファイルをARKitで使うサンプルを追加しました。

(本サンプルはiOS 11で動作させています)





  1. "usdz is supported on iOS and macOS, in SceneKit and Model I/O"と、サポートされている旨だけはサラッと述べられたが、これだけ。 



  2. USDZのベースとなるフォーマットUSDは"Universal Scene Description"の略です。 



  3. TwitterでGemmbuさんに教えていただきました。