GodotEngineでMorphを行う方法

結果を先に書いてしまうと、GodotEngineはMorph(いわゆる頂点アニメーション)を行う機能自体は実装されているのですが、仕様上の制限とバグのため、利用するには幾つかの工夫が必要です。

GodotEngineは現在Version3が開発中ですので、そちら側で修正される可能性もありますので、2系で頑張っている人向けです。(なんだかPythonみたい…)

 Morphの例1

 Morphの例2

上記のモデルデータはMilboxが公開している九十九みるを使用しています。

GDScript側からの制御は簡単で、あらかじめ設定されているパラメータをset関数で設定すると、元の頂点と変更先の頂点の値をブレンディングしてくれます。

func _process(delta):
    self.set("morph/wa", 1.0)

関連情報 https://godotengine.org/qa/528/where-get_morph_target-set_morph_target-amount-functions

この辺りはマニュアルに詳しく触れられていないのですが、set関数とget関数はnodeの属性を設定するための関数です。GodotEngineのエディタ上に表示されているパラメータをGDScriptから変更するために使用します。(今回の例では、MeshInstanceに存在するモーフターゲットを設定しています。)

 GUI上に表示されているMorph一覧

データの作成方法

操作する事は簡単なのですが、最大の問題はどのようにデータを作成するかという点です。

GodotEngineを使用している方でしたら、何らかのソフトウェアからCollada形式でエクスポートする事になるはずですが、どうも幾つか不具合がある様で、Morph付きでモデルデータを読み込むことが出来なかったり、読み込むことが出来ても動作しなかったりします。(参考情報 https://github.com/godotengine/godot/issues/7668

調べてみたところ、Morph機能自体は正常に動作しているのですがSkeleton機能を同時に使用する場合に正しく動作しない事が判明しました。また、オフィシャルが提供しているCollada形式のエクスポーターも正しく動作していないようです。

少なくともMorph機能自体は動作しているため、データさえ作成出来ればGodot上でさせられるます。

Colladaを介さずにGodotEngineにデータを渡す

Colladaを使用するとColladaファイル + GodotEngine側のColladaローダーを経由する為、この経路上に問題があると正しくGodotEngine側にデータを送り込む事が出来ません。

幸いな事にGodotEngineは自身のデータを「バイナリ」と「テキスト」のどちらでも読み書き出来る様になっている為、テキスト形式を使用してGodotEngineに直接送り込む事にします。

とりあえず作成したツール

そんなわけでcollada形式からtres形式に変換可能なツールを作成しました。

collada2tres https://github.com/MizunagiKB/collada2tres

# 使用方法
$ collada2tres.py -i input_collada_file -o output_tres_file [-m material]

-i にCollada形式のファイル名を与えて、 -o に変換後のファイル名を指定します。
-m でマテリアル名を指定すると、指定したマテリアルのみを出力します。

-m はカンマ区切りで複数のマテリアルを指定可能です。(-m face,body 等)

補足)

GodotEngine標準のColladaローダーではScene形式で保存されるのですが、こちらはMeshファイルとして保存されます。そのためSkeleton部分の生成がされません。(ボーンの割り当てと頂点ウエイトについては埋め込まれます。)

Morph可能なデータの制限

軽く確認したところでは、Morph可能なデータは対象のSurfacesが一つだけとなっている必要があります。作成済みのモデルを分解するのはかなり面倒なのでcollada2tresでは、-mでマテリアルを指定する事が出来る様になっています。

.

実際の動作確認用サンプル

GitHubに置きました。

WindowsとMacOSX用のバイナリも置いてあります。(初めてGitHubのリリース機能を使ってみました)

https://github.com/MizunagiKB/tsukumo_face

 こんな感じのデモです。

デモの内容と関係ありませんが、描画は平行投影で行なっています。(その方がかわいく描画されるから…)