LoginSignup
12
8

More than 5 years have passed since last update.

MathematicaでMikuMikuDance 1

Last updated at Posted at 2016-04-08

MikuMikuDanceの3次元CGモデルデータであるPMDファイルをMathematicaで可視化します。Mathematica8以降なら実行できると思います。RaspberryPiのMathematicaでも実行可能ですがとても重いです。
Bone7.png
素材のキャラクターは初音ミクです。
「初音ミク」はクリプトン・フューチャー・メディア株式会社の著作物です。
© Crypton Future Media, INC. www.piapro.net

1.PMDファイルをMathematicaで読み込めるファイルを準備する。

PMDファイルはバイナリ形式なのでMathematicaで直接読み込むのは難しいです。なのでC言語で変換プログラムを作成し、Mathematicaで読み込めるテキスト形式に変換しました。
今回はこのテキストファイルをMathematicaにImportして3D CGモデルを可視化していきます。
テクスチャデータはbmpファイルなので、そのまま画像ファイルとしてMathematicaに読み込む事ができます。
下記のGoogle DriveのURLリンクからhatsune2.mとeyeM2.bmpをダウンロードしてMathematicaの作業ディレクトりに置いてください。
Google Drive

変換元の3D CGデータのPMDファイルはMikuMikuDanceのデフォルトモデルである、あにまさ式ミクさんを使用しました。
あにまさ式ミク

2. Importする。

まずMathematicaの作業フォルダをDirectory[]で確認します。作業フォルダを変えたい時は、SetDirectory["作業フォルダ"];を実行します。

In[2]:= Directory[]

次に漢字コードを確認します。

In[33]:= $CharacterEncoding
Out[33]= "ShiftJIS"

ShiftJISで無かった場合は、ShiftJISに設定してください。(MMDはMS-Windowsのアプリケーションなので・・・。)

In[34]:= $CharacterEncoding = "ShiftJIS";

先ほどダウンロードしたhatsune2.mをImportします。

In[35]:= Pmd = Import["hatsune2.m"];

PMDのデータにアクセスする関数fを定義します。

In[36]:=  f[s_] := Pmd[[Position[Pmd[[All, 1]], s][[1]][[1]], 2]];

PMDデータがImport出来たか確認します。

In[37]:=  Pmd[[1]]
Out[37]= {"Header", {{"Magic", "Pmd"}, {"Version", 1.}, {"ModelName", 
   "初音ミク"}, {"Comment", "PolyMo用モデルデータ:初音ミク ver.2.3
   (物理演算対応モデル)

   モデリング  :あにまさ氏
   データ変換  :あにまさ氏
   Copyright    :CRYPTON FUTURE MEDIA, INC"}}}

3.とりあえず頂点データをプロットする。

3D CGモデルはポリゴンという単純な図形を組み合わせて構成されています。
PMDデータは三角形ポリゴンで構成されています。その三角形の頂点リストをListPointPlot3Dでプロットしてみます。

In[38]:= ListPointPlot3D[f["VertexVectors"]]

名称未定義-1.png

頂点リストのx,y,z座標を10点ほど見たい時はPart ( [[...]] )を使います。

In[39]:= f["VertexVectors"][[1;;10]]

Out[39]= {{-6.9072, 11.4279, -0.4254}, {-6.8439, 11.4035, -0.4289}, {-6.8689, 
  11.4285, -0.4475}, {-6.9102, 11.4319, -0.3639}, {-6.8759, 
  11.4352, -0.3439}, {-6.85, 11.4096, -0.358}, {-6.8992, 
  11.4757, -0.3624}, {-6.8979, 11.4742, -0.4303}, {-7.0481, 
  11.3895, -0.2397}, {-6.9938, 11.3629, -0.2471}}

4.ポリゴンで可視化する。

先ほどの頂点リスト3組で三角形ポリゴンを構成しGraphics3Dで可視化してみます。
どの3組を使うかはFaceIndicesに番号で格納されています。

In[38]:= f["FaceIndices"][[1]]
Out[38]= {647, 649, 648}

この3点で3角形ポリゴンの頂点を構成するには、このインデックス情報を頂点リストにMap( /@)すれば良いです。但しPMDデータ(C言語の配列)は0オリジンでMathematicaのリストは1オリジンなので#+1とします。

 In[39]:= f["VertexVectors"][[# + 1]] & /@ f["FaceIndices"][[1]]
Out[39]= {{-1.3489, 0.2482, 0.3302}, {-1.2294, 0.1478, 
  0.0412}, {-1.2595, 0.1478, 0.2643}}

Graphics3DコマンドでPolygonを可視化します。

Graphics3D[
 Polygon /@ (f["VertexVectors"][[# + 1]] & /@ f["FaceIndices"])
 ]

名称未定義-2.png

ポリゴンのエッジを消して表示してみます。

Graphics3D[
 Prepend[
  Polygon /@ (f["VertexVectors"][[# + 1]] & /@ f["FaceIndices"]),
  EdgeForm[]
  ]
 ]

名称未定義-3.png

面法線で陰影付けされたポリポリした(角ばった)ミクさんが表示されました。

5.各頂点に法線ベクトルを追加する。

各頂点に法線ベクトルのリストを追加します。これにより、グーローシェーディングで滑らかにミクさんを表示する事ができます。

Graphics3D[
 Prepend[
  Polygon[#[[1]], #[[2]]] & /@ 
   ({
       f["VertexVectors"][[# + 1]],
       VertexNormals -> f["NormalVectors"][[# + 1]]
       }
       & /@ f["FaceIndices"]),
  EdgeForm[]
  ]
 ]

名称未定義-4.png

6.各ポリゴンにテクスチャとマテリアルカラーを追加する。

各ポリゴンのプリミティブの前で色(マテリアルカラー)と模様(テクスチャ)を設定し、各ポリゴンの頂点にテクスチャ座標を設定します。

Graphics3D[
 Prepend[
  Flatten[#, 1] & /@
   Partition[
    Riffle[
     f["TextureList"][[# + 1]] & /@ f["MaterialIndices"],
     Polygon[#[[1]], #[[2]], #[[3]]] & /@ 
      (
       {
          f["VertexVectors"][[# + 1]],
          VertexNormals -> f["NormalVectors"][[# + 1]],
          VertexTextureCoordinates -> f["UVVectors"][[# + 1]]
          }
          & /@ f["FaceIndices"]
       )
     ]
    , 2],
  EdgeForm[]
  ]
 ]

名称未定義-5.png
いわゆるペンギンポーズをしたミクさんが表示されました。

7. 今後の予定?

クォータニオン演算、VMDファイルを使ってBoneによるポーズ付け、表情モ―フィングに続けて行きたいと思いますが、インバースキネマティクスと、クルっとターンした時の演算誤差の問題がまだ解決できていないので、その辺りを一緒に考えてくださる方がいらっしゃいそうなら順次、こちらで知っている事を公開していきたいと思います。それとC言語の話しになりますが、PMD,VMDファイルの変換についても書きたいと思います。

8. わからないこと

  1. WolframCloudでファイル共有って出来るのかな。。。今回はGoogleDriveを使用しました。

  2. 【解決】Mathematicaで3Dプロットした時にマウスでViewPointなどを調整した時、そのViewPointの情報を得る方法があったと思いましたが、どうやったか忘れてしまいました。。。
    【解決法】入門MathematicaP71より。

    Options[#,{ViewPoint}]& で回転したグラフィックスのViewPointが得られます。

9. 関連リンク

12
8
0

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
12
8