2019年3月30日土曜日

MMDの3DキャラをSceneKitに表示させたい

WindowsにMikuMikuDance(MMD)ってアプリがあって、3Dキャラをアニメーションで踊らせたりできるわけだが、そのキャラをiOSのSceneKitに表示してみたいと考えた。
特にARKitを使ってけものフレンズのサーバルちゃんとかを室内に表示させたり。

調べてわかったのが以下のやり方。
Blenderとadd-onがダウンロードできるアドレスは自分で調べてください。

  1. 3DソフトBlenderとadd-on機能を使って、MMDの.mmxファイルをiOSで扱える.daeフォーマットに変換。
  2. Xcodeプロダクトに変換したdaeファイルをAdd。
  3. ARKitのサンプルコードを使って表示。

1:.pmxファイルを.daeファイルに変換

Blenderとadd-onのプラグインをダウンロードし、以下のBlenderの設定フォルダにプラグインを入れる。
Macintosh HD⁩/ユーザ/(⁨ユーザ名)/ライブラリ/Application Support/Blender/(アプリのバージョン。たとえば2.79)/scripts/addons 

しかし、アプリ起動しただけじゃ設定フォルダが作られないらしい。File / UserPreferences... でウィンドウを開き、Save User Settingsを押すとできるようだ。それでもプラグインをしまうscriptsフォルダ以下ができないみたいなので、自作することになった。scripts、addonsと複数形なので間違えないように。

‎またそのフォルダに入れるのはblender_mmd_tools-masterフォルダ内のmmd_toolsフォルダ以下だけ。
BlenderのUser Preferencesウィンドウを開いてAdd-onsのObject:mmd-toolsにチェックを入れると、.mmxファイルのインポートができるようになる。

.daeにエクスポート

拡張子.daeは正式にはCOLLADAっていうんだね。
エクスポート時は対象となるオブジェクトを選択し、以上のようにいくつかボタンをチェックし(チェックを外すのも)、コンボボックスからレンダーを選んでから行う。

2:プロダクトに.daeファイルをAdd

.pmxファイルをインポートし.daeファイルにエクスポートしたら、それをXcodeのart.scnassetsフォルダにaddする。
.daeファイルだけでやっている人がいたのだが、それだけだと当然テクスチャーが表示されない。しょうがないのでテクスチャーその他を含んだフォルダごとaddした。
その状態でその.daeファイルを選択すると、ちょっと時間がかかるがXcode上に3Dキャラが表示される。
もしその中にrigidbodiesというカテゴリができていたら、いらないらしいので削除しちゃっていい。
表示はすごく拡大されて歪んでるので、scaleなどを調整してやらないといけない。

保存できない問題が

.scnファイルをいじった後、RunやSaveしようとすると
The document “serval.dae” could not be autosaved. Your changes will not be saved until the problem is resolved.
などと出てなぜか保存できないことがあった。

どうやらHomeフォルダ以下のPermissionがおかしくなってたらしく、以下の2つのサイトを参考にPermissionの修復をしたところ、無事に保存できるようになった。
Homeフォルダ以下全てのファイルを修復するようなので、結構時間はかかる。
https://forums.developer.apple.com/thread/109669#335313
https://support.apple.com/en-us/HT203538
うちの環境だけの問題かもしれない。
EditorメニューのConvert to SceneKit scene file format (.sce) を選んで.scnファイルに変換する。 

2019年3月26日火曜日

Swift5が出た

Xcode10.2が出て、Swiftが5になったので、気づいた点だけまとめる。
(ついでにiOS12.2になってmacOS 10.14.4もリリースされた)
他にも色々あると思うけど、難しい使い方しなきゃあんまり使わないのもあると思うので。気づいたら追記します。

気づいた変更点

#のリテラル

" "だけでなく、# #で囲うことで、\ なしで " などを文字列の中で扱える。
書き方によってはスッキリするってことかな?

let a = "new"
var str = #"Hello, "the" \#(a) world"#

結果は
Hello, "the" new world
になる。

isMultiple( )

これまでは%で余りを求めることである数の倍数かどうか調べていたが、今後は .isMultiple()関数 で置き換えることができる。
以下の2つの結果は同じ「割れる」になる。

let ans = 10
if ans % 2 == 0 {
print("割れる")
} else {
print("割れない")
}

if ans.isMultiple(of: 2) {
print("割れる")
} else {
print("割れない")
}