CrossRoad

Unity、VR、MR、ARを中心とした技術ブログ

Blenderでロボットにボーンとモーションをつけて、Babylon.jsで再生させる方法

今回はBabylon.jsで3Dモデルにアニメーションをつけて再生させてみました。Babylon.jsだけでもオブジェクトの移動(UnityでiTweenを使うようなイメージ)はできますが、ボーンを埋め込んだモーションの実現をソースコードだけで作るのは大変そうです。Babylon.jsの公式HPをみると、Blenderの使用が紹介されていました。

手順はこのようになります。

  • (1) Blenderでボーン埋め込みとモーションを付加
  • (2) Babylon.js向けに出力するプラグインでデータを出力
  • (3) Babylon.jsで再生

試したところ、(2),(3)の情報があまりなく詰まったので、一通りの手順やTIpsを整理しました。

なお、以下の環境で動作を確認しています。

  • Blender : v2.79 (Mac)
  • Chrome  :68.0.3440.106
  • Babylon.js :v3.2.0

0. Blenderを準備する

(ここはBlenderを使ったことがある方には不要です)

今回、初めてBlenderを使ったので、インストールから基本的な使い方を残しておきます。まず、インストールですがWindows、Macのどちらでも動きました。動作未確認ですが、Linuxでも動くとのことです。

Blenderインストーラのダウンロード場所

インストールは画面の指示に沿って進めるだけなので、説明を省略します。私はMacで使っており、基本設定や操作方法はこちらの記事を参考にさせていただきました。

Blender Mac版 の操作方法や基本機能の使い方 - Project Unknown

いきなり全部を覚えるのは大変なので、まずは記事の中の「テンキーの模倣」の設定を済ませ、「視点操作」を確認しておくと最低限動かせるようになります。

その他、BlenderはObject Mode、Edit Mode、Pose Modeのように、同じ3D viewの画面で異なるモードを実行できます。概念的ですが、今回は3つのModeを以下のように使いました。

  • Object Modeは、メッシュの移動、回転、拡大などに使った
  • Edit Modeは、ボーン を埋め込むときに使った
  • Pose Modeは、メッシュとボーン の対応づけをしたあとの動作確認、アニメーションの埋め込みに使った

(Modeは他にもありますが、今回は割愛します)

1. Blenderでボーンを付加する

1.1 モデルの結合

まずはモデルを準備します。ロボットを動かしてみたかったので、下記のサイトより取得しました。また、ライセンス規約を確認し、個人での使用は問題ないと判断しました。

Gareth (War Robots) 3d model - Free3D

Free3Dのライセンス規約

中にはBlenderのプロジェクトファイル(.blend)が入っているので、Blenderで開きます。開くとこのようになります。

Free3Dのgareth-87493をBlenderv2.79で開いた時の画面

このロボットは、boxとclylinderが多数分かれた状態で格納されています。

Free3Dのgareth-87493のmesh分割状況

このままだとボーンを入れるのも、位置や大きさの調整も大変なので、選択して結合します。結合は、下記のようにoutlinear view(写真の右側)で2つ以上のメッシュをshiftキーを押しながら選択し、object modeで joinを選択します。

Blenderでjoin処理を行う例

最終的に結合してこのようにしました。もう少し下層にも配置していますが、ここでは表示していません。

Free3Dのgareth-87493のメッシュを結合した例

1.2 ボーンの埋め込み

このロボットにボーンを入れていきます。ボーンの入れ方については下記がとてもわかりやすく、基本的にこの通りに進めました。

【Blender】ボーンを入れる(リギング)ための基本手順 - おもちゃラボ

まずはボーンを埋め込みます。
Free3Dのgareth-87493にボーンを埋め込んだ画面

このときボーンの位置や大きさを変えたり、先端を基準に次のボーンを出す必要があります。しかし、マウスクリックだけでは先端が選択できなかったので、ctlを押しながら先端を囲むことで実現できました。

Edit Modeでボーンの先端を選択する例

埋め込んだら、メッシュ、Armatuarの順番に選択します。上の記事でも言及されており、Blender全般に言えますが、何かを複数選択した時は、最後に選択したものの要素を基準に指定します。今回はArmaturarの機能を使うのでArmatuarを最後に選択しました。

次に、ctrl+pを押してから、With Automatic Weightsを選択します。

BlenderのWith Automatic Weights設定画面

上の記事でも書いてありますが、ボーンを埋め込んでも意図した通りに動きませんでした。outlinear viewで該当するメッシュを選択してから、ctl + tabを押すと、Weight Paintモードになります。

BlenderのWeight Paintの実行例

Weight Paintでは、そのボーンと関連の強いメッシュが赤く表示され、関連が薄いと青くなります。マウスで動かすと上のgifのように赤くなります。それぞれのボーンについて、関連の強いメッシュを赤く塗っていくと、メッシュが意図した動きになります。

しかし、今回試した範囲では前半のメッシュの結合が悪いのか、Weight Paintがうまく使えていないか、一部のメッシュがくっついてしまいました。この辺りはBlenderの慣れの問題なので、もう少し慣れたらまた試してみたいと思います。

1.3 Object / Applyの実行

次に、position, rotation, scaleを調整します。Object Modeのときに、Object / Apply / Rotation & Scale を実行します。すると、それぞれの値が0になります。これを全てのオブジェクトに適用します。

これはBlenderのチュートリアルや関連記事、Babylon.jsの公式HPでも記載がなく、下記の投稿で見つけました。

blender - How to fix Object has unapplied transformations. This will never work for a mesh with an armature. Export cancelled - Stack Overflow

もしこの手順を実行しないと、後でBabylon.js向けに出力してもこのようなエラーが出て失敗します。

Mesh: UpperHead has un-applied transformations.  This will never work for a mesh with an armature.  Export cancelled
========= end of processing =========
elapsed time:  0 min, 22.2191 secs

2. Blenderでアニメーションを作る

アニメーションを作るには、Dope Sheetという機能を使います。Dope Sheetはこのように出します。

BlenderでDope Sheet画面を出す手順

他のブログでも言及されており、上のgifでも最後に表示していますが、Dope SheetのAction Editorでアニメーション用のファイルを定義したら、Fボタンで保存する必要があります。(こうしないと、アニメーションが保存されないようです)

アニメーションの基本的な考え方ですが、モデルをあるポーズにしてから記録、別のポーズにしてから記録、を繰り返し、ポーズとポーズの間の動きをコンピュータで補完することで実現しています。ポーズ間の動きを補完してくれるように記録したものをキーフレームと呼びます。

キーフレームの打ち方はこちらを参考にさせていただきました。

初心者のための!作って学ぶBlenderの基礎:⑤アニメーションを設定する | 日本VTR実験室

キーフレームを打ったあとalt+Aを押すと、作ったアニメーションを再生できます。

Blenderで作ったアニメーションの例

ボーンとメッシュの連携がおかしくて足の一部のメッシュが動いてませんが、歩行モーションらしきものができました。
(なお、ここでは見やすいようにロボットの盾を非表示にしています)

次に、作ったアニメーションをbakeします。このように、対象のメッシュとボーンをshiftキーで選択してからspaceキーを押します。続けて、出てきたウインドウでBake Actionとタイプします。
出てきたウインドウで、Only Selected, Visual Keying, and Clear ConstraintsにチェックをつけてからOKします。

BlenderのBake Actionの手順

この後に、再度メッシュ、ボーンの順番にshiftキーで選択して、ctl + p、Use Automatic Weightsを実行しています。ただ、もしかするとUse Automatic Weightsはここで初めて実行しても良いのかもしれません。再確認して必要あれば修正します。

なお、Bakeしないと、後のBabylon.jsでアニメーションが実行できず、Babylon.js公式HPではその手順が書いていませんでした。こちらの記事を参考にさせていただきました。

Blender animation export problem - Questions & Answers - HTML5 Game Devs Forum

3. Blender to Babylon.js exporterをインストールする

次はBabylon.js向けに3Dモデルとアニメーションデータを出力します。出力にはBabylon.jsから提供されているBlender to Babylon.js exporter(以下、Exporter)を使います。これはBlenderのプラグインでGithubで公開されています。

Blender to Babylon.js exporterの概要説明

Exporters/Blender at master · BabylonJS/Exporters · GitHub

Githubからダウンロードしたら、Blender/Blender2Babylon-5.6.zipを取り出し、任意の場所に置きます。インストールの手順はBlender to Babylon.js exporterの概要説明のInstallationに記載の通りですので省略します。

Install Add-on from File をクリックすることでインストールできますが、「インストールに成功しました」のような表示は出ず、見た目では何も変化しません。

4. Exporterで出力する

Blender to Babylon.js exporterの概要説明に機能紹介は書いてありますが、どこから使うかがわかりづらかったので補足します。

まず、Exporterの設定画面は、outlinear viewで何らかのオブジェクトを選択して、Sceneを意味するオプション?を選択して下にスクロールすると出てきます。

Blender to Babylon.js exporterの画面の出し方

今回はExportの対象をAllにすることで、ロボットの3Dモデルとアニメーションを出力できました。また、Write Manifest Fileは不要でした。その他、色々と設定がありそうですが、まだ確認できていません。確認できたら追記するか、別の記事でまとめたいと思います。

5. Babylon.jsのコードを書く

先ほど出力したのは.baylon形式のファイルとテクスチャです。Babylon.jsの公式HPには書いておらず、Babylon.jsのHPやフォーラムの投稿を参考にして作ることで、アニメーションを再生できました。

最終的にこのようなコードを書きました。


gist952f21c40346b2894658043f31d930f0

BABYLON.SceneLoader.ImportMesh()によって、.babylonからメッシュ情報、スケルトン情報を取り出します。beginAnimation()によってアニメーションを実行しています。

なお、ソースコード中のコメントに記載の通り、beginAnimation()の第一引数はrobotSkeltonにすると動きましたが、サンプルコードに記載のskeltons[0]では動きませんでした。 

6. 動作を確認する

.babylonファイル、テクスチャ、先ほど書いたhtmlファイルを同じディレクトリに入れてからChromeでhtmlを開きます。

Blenderで作ったアニメーションをBabylon.jsで再生した例

Blender側で再生したのと同じ状態で再生されています。胴体部のテクスチャがおかしいですが、これはBlender側のオブジェクト結合処理に問題がある可能性が高いので、後日直す予定です。

htmlを開いても何も表示されず、デベロッパーツールで以下のようなエラーが出た場合はCross Originエラーが原因です。

babylon.js:1 Failed to load file:///<filepath>/data.babylon: Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https.

このようなときは、Webサーバにデータをアップロードするか、Macの場合は/Library/WebServer/Documentsの中にデータを置いて、

http:///<フォルダがある場合はフォルダ名>/.html

とアクセスしてください。

7. 終わりに

Exporterの結果を取り込んで再生する、というだけなのですが、情報が点在していて解決に時間がかかりました。でもこれでCGに動きをつけられるようになったので、次回はもう少し複雑なことをしてみようと思います。