Blenderを使って3Dデータを作成&表示させてみよう
これまではサンプルをベースに紹介をしてきましたが、実際にアプリを作成する際には独自の3Dデータを表示することになると思います。
3DモデリングはShadeやAutoCADなどの有償ソフトで行うことが多いですが、個人アプリ開発の場合では無償のBlenderでも十分こと足りると思います。
今回はBlenderを使って3Dデータを作成する方法と、ARKitで表示する方法を紹介します。
Blenderのインストール
この記事作成時のBlenderの最新バージョンは2.8.0になります。
こちらからBlenderをダウンロードしインストールを行います。
2.7.9では日本語化するには別途作業が必要でしたが、2.8.0ではデフォルト日本語に対応しています。
3Dデータの作成
Blenderを使って木の箱とボールを作ります。
Blenderを起動すると下記のようなデフォルトプロジェクトが表示されます。
まずは、カメラとライトは不要なので右のアウトライナーから右クリックで選択し「削除」を実行します。
木の箱はデフォルトのCubeを使うため、ボールを追加します。
オブジェクト画面のメニューより追加 > メッシュ > UV球を選択します。
こちらのカーソルの位置に球が作成されるので事前に配置したい位置にカーソルを移動しておきます。
デフォルでは「球」となっていますが、ARKit内で操作し易いように右のアウトライナーより名前を「Ball」に変更しておきましょう。
ひとまず、シーンの中に箱とボールを作ることができました。
3Dデータのエクスポートとプロジェクトへの追加
Blenderメニューのファイル > エクスポート > Collada (.dae) を選択してデータをエクスポートします。
ここでは3d_data.daeと名前を付けてエクスポートを行います。
作成したdaeファイルはXcodeのプロジェクトにドラッグ&ドロップで追加を行います。
もし、art.scnassetsのアセットカタログがプロジェクトにあるのであればそこに追加を行いましょう。
※art.scnassetsがCopy Bundle Resourcesに追加されている場合は不要です
scnファイルへの変換と位置の調整
このままdaeファイルの状態でも3Dデータを読み込むことはできるのですが、データ表示位置の調整やテクスチャの設定はscnファイルの方がやり易いのでdaeファイルをscnファイルへと変換を行います。
Xcodeの左のペインより、3d_data.daeを選択し、メニューの Editor > Convert to SceneKit scenn file formatを実行します。
これでファイルがscnファイルへと変換され下記のように表示がされます。
3Dカーソルがこのデータの原点になります。そのため、このままAKitでテープル上にデータを表示すると、テーブルにボールの半分がめり込んでしまいます。
そのため、面倒でも一度SCNNodeを親に設定し、表示位置を調整する必要があります。
左のScene graphより「+」を選択し、ノードを追加します。
この時の名前は対応付けがわかるようにCubuNodeとしておきます。
CubeNodeを作成したらScene graph上でCubeでCubuNode配下に移動させます。
そして、CubeNodeがを選択した時に3Dカーソルがデータの底に来るようにCubeの位置を変更します。
3Dカーソルの緑の矢印(Y軸)を選択して移動させます。
このとき視点が真横に来ないと調整が難しいですが、画面の左下にあるカメラマークでFrontを選択しておくと視点が真横に来ます。
調整が済むとこのような状態になります。
テクスチャ、色の設定
このままだと真っ白なデータが表示されてしまうためテクスチャの設定と色の設定を行います。
- 箱 → 木目のテクスチャを設定
- ボール → テクスチャを使わず、紫色の設定
まずは箱の設定にテクスチャを設定します。
daeファイルを読み込んだときと同様にテクスチャ画像をXcodeプロジェクトにドラッグ&ドロップします。
次に右のペインでマテリアルのタブを選択します。
このときMaterialsに何も表示されていなかったら「+」ボタンを押して新しくMaterialを追加してください。
この状態ではPreviewは味気のない球が表示されているはずです。
Properties > Diffuseを選択し先程追加した画像を選択します。
このとき画像と一緒に色も選択肢として表示されましたが、画像でなく色を選択すれば3Dデータに色をつけることができます。
ボールも箱と同様にDiffuseを設定します。
うまく設定ができれば最終的にはこのようになります。
プログラムへの読み込み
ここまで来たら最後はプログラム上で作成した3Dデータを読み込むだけです。
サンプルの飛行機を読み込んだときと同じようにファイルを指定して読み込むだけです。
具体的には下記のように書きます。
guard let dataScene = SCNScene(named: "art.scnassets/3d_data.scn") else { return }
if let node = dataScene.rootNode.childNode(withName: "cubeNode", recursively: true) {
sceneView.scene.rootNode.addChildNode(node)
}
3d_data.scnでは二つの3Dデータを含んでいます。
読み出したいデータに合わせてchildeNode()で検索する名前を変更します。
なお、ここで気をつけて欲しいのは、検索する名前は3Dデータ自体ではなくその親ノードを指定することです。
直接3Dデータを読み込むことができますが、原点が底に来ていないため想定した位置とずれてしまうことになるので注意してください。