LoginSignup
46
45

More than 5 years have passed since last update.

MMM(MikuMikuMoving)でPerception Neuronを使う

Last updated at Posted at 2016-01-06

※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※
MikuMikuMoving v1.2.8.0で公式にPerception Neuron対応されましたので、
現在こちらのプラグインを使用する必要はありません
※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※

Perception Neuronとは


中国Noitom社によって開発された低価格モーションキャプチャシステム。公式サイトはこちら。最大32個のNeuronと呼ばれる9軸センサモジュール(3軸ジャイロ+3軸加速度+3軸磁気)を用いて指先を含めた全身のキャプチャが可能。Axis Neuronという専用ソフトからTCP/UDPによるBVHフォーマットのモーションデータを送信することができます。システム一式(Neuron32個付属)で$1,499。Axis NeuronはこちらからFree版をダウンロードすることができます。Perception Neuronを持っていなくてもサンプルのモーションデータを再生させることができます。

MMM(MikuMikuMoving)とは

001.PNG

Mogg氏により開発されているMikuMikuDance(MMD)互換ソフト。公式サイトはこちら。MMD用のモデルやモーションデータが使用可能。プラグイン機能を持っており、ユーザーが自由に機能を追加することができます。

今回、Axis Neuronから送信されたモーションデータをMMMで受信し、MMDモデルにモーションを反映させるプラグインを作成しました。実装した内容について書きたいと思います。

MMMのプラグイン開発

MMMのプラグインの開発に必要なソフトウェアと環境は以下になります。

開発に必要なソフトウェア
・Microsoft Visual C# 2010 Express もしくはこれに準じるソフトウェア

必要環境
・Windows XP以降
・.NET Framework 2.0
・DirectX 9.0c Runtime 2010 Feb以降 (SDKは必要ありません)

※MMM公式サイト 17.プラグインより引用

プラグインには、ボタンを押したときに実行されるコマンドプラグインと、毎フレーム実行される常駐型プラグインの2種類のタイプがあります。これらのプラグインでは、モデル、アクセサリ、エフェクト、カメラやライトに対して、キーフレーム操作やモーション操作等が可能です。プラグイン開発については詳しくはMMM公式サイトの17.プラグインをご確認ください。今回は常駐型プラグインで開発しました。

モーションデータの受信

NeuronDataReaderライブラリ

Axis NeuronはTCP/UDPによるBVHフォーマットのモーションデータを送信することができます。NeuronDataReaderというC/C++用ライブラリが提供されており、これを利用することでBVHデータの受信を簡単に行うことができます。

キャプチャ.PNG
※画像は「Neuron Data Reader Runtime API Documentation」1.1. NeuronDataReader frameworkより引用

BVHデータフォーマット

毎フレームのデータにはBVHヘッダとBVHモーションデータが含まれます。BVHヘッダには、位置情報の有り無しやリファレンスデータの有り無しなどの基本的な情報が含まれます。

// Header format of BVH data
typedef struct _BvhDataHeader 
{
 uint16_t Token1; // Package start token: 0xDDFF
 DATA_VER DataVersion; // Version of community data format. e.g.: 1.0.0.2
 uint16_t DataCount; // Values count
 uint8_t WithDisp; // With/out displacement
 uint8_t WithReference; // With/out reference bone data at first
 uint32_t AvatarIndex; // Avatar index
 uint8_t AvatarName[32]; // Avatar name
 uint32_t FrameIndex; // Frame data index
 uint32_t Reserved; // Reserved, only enable this package has 64bytes length
 uint32_t Reserved1; // Reserved, only enable this package has 64bytes length
 uint32_t Reserved2; // Reserved, only enable this package has 64bytes length
 uint16_t Token2; // Package end token: 0xEEFF 
}BvhDataHeader;

※コードは「Neuron Data Reader Runtime API Documentation」2.1.4. Header of BVH data streamより引用

BVHモーションデータは連続したfloat値になっています。リファレンスデータ有りの場合、最初の6つのfloat値はリファレンスボーンの位置と回転になります。位置情報有りの場合、すべてのボーンが6つのfloat値(位置xyzの3つと回転xyzの3つ)を持ちます。位置情報無しの場合、ルートボーンのみ6つのfloat値を持ち(位置xyzの3つと回転xyzの3つ)、それ以外のボーンは3つのfloat値を持ちます(回転xyzの3つ)。

009.PNG
※画像は「PERCEPTION NEURON UNITY HANDBOOK」APPENDIX D: BINARY DATA SEQUENCEより引用

回転の順序はYXZです(Axis Neuron側の設定で変更可能)。
また、ボーンの階層構造は「Neuron Data Reader Runtime API Documentation」Appendix B: BVH header templateに載っています。

C#でNeuronDataReaderを利用する

公式サイトからダウンロードできるNeuronDataReader SDKにはdemo_csというC#で開発されたサンプルプロジェクトがついてきます。このサンプルプロジェクトにはNeuronDataReaderWraperというC#からNeuronDataReaderを使うためのラッパクラスが含まれています。C#でNeuronDataReaderを利用する場合はこちらを使わせてもらいましょう。

また、公式サイトからダウンロードできるUnity IntegrationというUnity向けのパッケージに含まれているNeuronActor.csやNeuronTransformsInstance.cs、NeuronAnimatorInstance.csに、受信したデータから各ボーンの位置と回転を取り出したり、取り出した位置と回転を受信側のモデルのボーンに適用する処理が書かれています。こちらも参考になるかと思います(位置と回転はUnityの座標系に合わせて変換されているので注意してください)。

それぞれの座標系

Perception Neuronで使用される座標系

xの正方向が右、yの正方向が上、zの正方向が手前の右手系です。

キャプチャ.PNG
※画像は「Neuron Data Reader Runtime API Documentation」Appendix D: Skelton Graphより引用

MMMで使用される座標系

xの正方向が右、yの正方向が上、zの正方向が奥の左手系です。
MMMの画面上の座標軸はzが手前に伸びてますがマイナス方向なので注意です。

005.PNG

座標系の変換

以上より、位置に関してはzの値をマイナスに、回転に関してはxとyの回転を逆に回転させることで、Perception Neuron側の値をMMM側の座標系に合わせる事ができます。

Perception NeuronとMMMのボーンの対応

Perception NeuronとMMMのボーンは以下のように対応させました。MMDモデルのボーン構造はモデルによって違いがあったりしますが、標準モデルをベースに対応付けています。Perception Neuronからは各ボーンの位置と回転が得られますが、Hipsの位置をセンターの位置に使用している以外は、位置は使わず回転のみ使っています。上半身については、Perception Neuron側のSpine、Spine1、Spine2、Spine3の四つのボーンの回転を合計した値をMMM側の上半身ボーンに使っています。上半身2を持っているモデルの場合は、Spineを上半身、Spine1、Spine2、Spine3の合計を上半身2に使う等すると良いかと思います。また、RightHandIndex1とRightInHandIndexの回転を合計した値を右人指1ボーンに使っています。他の指も同様です。(このあたりはUnity IntegrationのNeuronAnimatorInstance.csのやり方を参考にしました)

Perception Neuronのボーン MMMのボーン
Hips(位置) センター(位置)
Hips 下半身
RightUpLeg 右足
RightLeg 右ひざ
RightFoot 右足首
LeftUpLeg 左足
LeftLeg 左ひざ
LeftFoot 左足首
Spine+Spine1+Spine2+Spine3 上半身
Neck
Head
RightShoulder 右肩
RightArm 右腕
RightForeArm 右ひじ
RightHand 右手首
RightHandThumb1 右親指1
RightHandThumb2+RightHandThumb3 右親指2
RightHandIndex1+RightInHandIndex 右人指1
RightHandIndex2 右人指2
RightHandIndex3 右人指3
RightHandMiddle1+RightInHandMiddle 右中指1
RightHandMiddle2 右中指2
RightHandMiddle3 右中指3
RightHandRing1+RightInHandRing 右薬指1
RightHandRing2 右薬指2
RightHandRing3 右薬指3
RightHandPinky1+RightInHandPinky 右小指1
RightHandPinky2 右小指2
RightHandPinky3 右小指3
LeftShoulder 左肩
LeftArm 左腕
LeftForeArm 左ひじ
LeftHand 左手首
LeftHandThumb1 左親指1
LeftHandThumb2+LeftHandThumb3 左親指2
LeftHandIndex1+LeftInHandIndex 左人指1
LeftHandIndex2 左人指2
LeftHandIndex3 左人指3
LeftHandMiddle1+LeftInHandMiddle 左中指1
LeftHandMiddle2 左中指2
LeftHandMiddle3 左中指3
LeftHandRing1+LeftInHandRing 左薬指1
LeftHandRing2 左薬指2
LeftHandRing3 左薬指3
LeftHandPinky1+LeftInHandPinky 左小指1
LeftHandPinky2 左小指2
LeftHandPinky3 左小指3

Perception NeuronのモーションをMMMに適用させる

Perceoption NeuronのモーションをMMMに適用させるために、プラグイン内で以下のような処理を行っています。

デフォルトポーズの違い

Perception NeuronのデフォルトポーズはTスタンスですが、MMMのデフォルトポーズはAスタンスです。MMM側でTスタンス用のモーションデータを使えるように、モデルのポーズをAスタンスからTスタンスに変換します。肩、腕のボーンが地面と平行になるようにz軸回転させます。

はじめに、肩ボーンの、グローバル座標系のx軸に対する角度を求めます。次に、腕ボーンの、肩ボーンに対する角度を求めます。肩と腕それぞれ求めた角度分戻すとTスタンスになります。

006.PNG

007.PNG

また、親指が、Perception Neuron側では閉じているのに対し、MMM側では開いています。
032.PNG

Tスタンスに変換後、グローバル座標系のx軸に沿うように親指1ボーンをY軸回転させて、親指を閉じさせます。
033.PNG

ボーンの回転軸の違い

Axis Neuronから送信されるモーションデータの回転角はボーンのローカル座標系における回転角ですが、MMM側で回転を指定する際にはデフォルトポーズ時におけるMMMのグローバル座標系に一致したローカル座標系で指定することになります。
010.PNG

そのため、肩、腕、ひじ、手首、指についてはAxis Neuron側の回転をかける際に、Axis Neuron側とMMM側で回転軸が合うようにボーンを回転させておく必要があります。Tスタンスへの変換と合わせると、行列の計算は以下のようになります。

Tスタンスへの回転行列×「回転軸を合わせるための回転行列」の逆行列×肩、腕、ひじ、手首、指ボーンの回転行列×回転軸を合わせるための回転行列

親指1ボーンの場合は、上記計算に親指を閉じさせる回転を加えます。

親指を閉じる回転×Tスタンスへの回転行列×「回転軸を合わせるための回転行列」の逆行列×親指1ボーンの回転行列×回転軸を合わせるための回転行列

Perception NeuronのSpineボーンとMMMの上半身ボーンの違い

Perception NeuronのSpineボーンはHipsボーンの子ですが、MMMの上半身ボーンは下半身ボーンと親子関係にありません。MMM側で、Hipsボーンの回転を上半身ボーンにも適用させる必要があります。行列の計算は以下のようになります。

Hipsボーンの回転行列×上半身ボーンの回転行列

センター位置のリセット

直立時にセンターボーンのY座標が0になるように、直立時のPerception NeuronのHipsボーンのY座標の値をオフセット値として使っています。

プラグインの使い方

今回作成したプラグイン(NeuronReceiver.dll)をこちらで配布しています。Perception Neuronの公式サイトからAxis NeuronとNeuronDataReader SDKをダウンロードしてください。MMMはこちらからダウンロードできます。(上で説明した内容をプラグインの内部で処理しています。このプラグインを使うにあたって、モデルのTスタンスへの修正などは必要ありません)

Axis Neuronの設定

File->Settings->Broadcastingを選びます。TCPを選択し、BVHにチェックをいれてください。Portは7001にしておきます。
013.PNG

File->Settings->Output Formatを選びます。Frequency reducingは1、Block typeはBinary、RotationはYXZを選んでください。
014.PNG

動作確認用に適当なサンプルモーションを再生しておきます。
015.PNG

プラグインの導入

NeuronDataReader SDKのWindows\lib\x64\NeuronDataReader.dllをMMMの実行ファイルと同じフォルダなどパスの通っている場所にコピーしてください(32bit版のMMMを使用する場合はWindows\lib\x86\NeuronDataReader.dllを使用してください)。

011.PNG

Pulginsフォルダにプラグイン以外のdllを入れるとMMM起動時に以下のエラーになってしまうので注意してください。(対処法をサメジ部長 (@samezi)さんに教えていただきました。ありがとうございました)

キャプチャ.PNG

NeuronReceiver.dllをMMMのPluginsフォルダにコピーしてください。
011_1.PNG

MMMを起動してください。起動時に以下のエラーが出ることがあるようです。その場合は、こちらの対処方法を参考にしてください。

c0e7f37306d61dc29d020f218057df34.png

モデルを読み込みます。
016.PNG

足のIKをすべて切ります。
017.PNG

NeuronReceiverプラグインを有効化します。
018.PNG

NeuronReceiverプラグインのConnectボタンを押します。
019.PNG

Axis Neuronへの接続が成功すると以下のダイアログが表示されます。
020.PNG

接続に失敗すると以下のダイアログが表示されます。Axis Neuronが起動しているか確認してください。起動している場合は、Broadcastingの設定内容を確認してください。
021.PNG

接続直後はモデルが宙に浮いています。
022.PNG

直立時に、NeuronReceiverプラグインのセンター位置リセットボタンを押してください。モデルが接地します。
023.PNG

MMDモデルの体型によっては、移動時に足が滑ったり、しゃがんだときに地面に潜り込むことがあります。NeuronReceiverプラグインのY軸スケール係数とXZ平面スケール係数を調整することで、ある程度改善させることができます。
024.PNG

物理演算を有効化します。
026.PNG

こんな感じで動かすことができます。


モーションの記録

はじめに、0フレーム目に足のIKを切った状態をキーフレーム登録しておきます。NeuronReceiverプラグインのRecordボタンを押すと、モーションの記録を開始します。
025.PNG

Stopボタンを押すと、モーションの記録を停止します。
027.PNG

タイムラインにキーフレームが登録されます。キーフレームは全フレームに登録されます。
030.PNG

記録したモーションをMMM上で再生する場合は、NeuronReceiverのプラグインを無効化してから再生してください。また、PCの性能にもよりますが、大量にキーフレームを登録しているためか500~600フレームを超えたあたりからフレームレートが低下し、キーフレーム登録が飛び飛びになってしまうことが確認されています。

記録したモーションをMMDで使う

VMDフォーマットで保存します。
028.PNG

保存したVMDファイルを、MMDで読み込むことができます。
029.PNG

記録したモーションをUnityで使う

Noraさん(@Stereoarts)のMMD4Mechanimを使うことで、UnityでMMDモデルやMMDで作成したモーションを使うことができます。MMD4MechanimはStereoarts Homepageからダウンロードすることができます。詳しい使い方はこちらに載っています。

031.PNG

課題

腰の位置を基準として各ボーンに回転の値をセットしているだけなので、Perception Neuron側とMMM側とでモデルの体型が異なる場合、足先の位置が一致しません。そのため屈伸や前屈のような本来足先が動かない動作で、足先が動いてしまうことがあります。

また、Axis NeuronとUnity Integrationのサンプルとで比較すると、Unityの方では足先が動いてしまっているので、体型の違い以外にも何か原因があるのかもしれません。(Axis Neuronでは足の接地判定を行って足を固定している?)


46
45
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
46
45