JavaFX
MMD
PMD形式

PMD形式のMMDモデルをJavaFXで読み込んで表示する

とりあえずメモ書き程度。細かい処理とかはソースコードを参照。ここでは、PMDデータを読み込んでJavaFXで表示するまで。JavaFXの3D表示についてはここでは記載しない。

MMDモデルとは

樋口氏によって開発されたMikuMikuDance専用の3Dモデルフォーマット。PMD形式とPMX形式の2種類あり。

使用したMMDモデル

Twitter上で連載されている漫画「いきのこれ!社畜ちゃん」(ビタワン氏@vitaone_)の登場キャラクターのMMDモデルを使用。公開サイトはこちら
データ形式はPMD形式

PMD形式データ

バイナリ形式。基本的にデータフォーマットは非公開。以下のサイトを参考に読み込み部を実装。

通りすがりの記憶

JavaFXで3D表示

TriangleMeshとPhongMaterialを使用。PMDの頂点データと面データをそのまま使用すると、上下が逆転して表示される。これはY座標の正方向がPMDでは上、JavaFXでは下となってるため。
texture.jpg

なので、Y座標については+-を反転させて設定する。
ただし、Y座標の反転だけでは面の表裏が逆になってしまい正常に表示されない。
texture2.jpg

正常に表示させるために、面データの頂点3点を指定する順番を逆転させることで、正常に表示できる。
texture3.jpg

PMDのどのデータをどこに設定するか

PMDデータの詳細は通りすがりの記憶を参照。

TriangleMesh

TriangleMesh.getPoints().addAll()で、頂点リストのfloat[3] posを設定。
pos[0] = x, pos[1] = y, pos[2] = zとなるので、pos[1]の値は+-を反転

TriangleMesh.getTextCoords().addAll()で、頂点リストのfloat[2] uvを設定。
これはy座標の反転は不要

TriangleMesh.getFaces().addAll()で、面情報のWORD face_vert_index[]を設定。
face_vert_index[]の値3つで1つの面を表し、指定順を逆転させて指定するので、
{
face_vert_index[2], face_vert_index[2],
face_vert_index[1], face_vert_index[1],
face_vert_index[0], face_vert_index[0]
}
のようになる。(左側が頂点のインデックス、右側がテクスチャのインデックス)

PhongMaterial

テクスチャイメージ(javafx.scene.image.Image)は、材質リストのchar texture_file_name[20];で指定されているファイルを指定。

PhongMaterial.setDiffuseMap()に、材質リストのfloat diffuse_color[3]およびfloat alphaの値を使用してjavafx.scene.paint.Colorで設定。

PhongMaterial.setSpecularColor()に、材質リストのfloat specular_color[3]の値を使用して(アルファ値は1.0固定)javafx.scene.paint.Colorで設定。

PhongMaterial.setSpecularPower()に、材質リストのfloat specularityを設定。

ざっくりと説明するとこんな感じ(ほんと超ざっくりw)

ソースコード

ソースコードはこちら。
https://github.com/nekog1975/fxmmd

使い方

PMDLoader.load(Path)でPMDクラスを生成し、PMDConverter.convert(PMD)でListを生成して使用する。(ソースコード中のtest.TestMain.javaを参照)

実行結果

後輩ちゃん
後輩ちゃん.jpg

先輩さん
先輩さん.jpg

同期ちゃん
同期ちゃん.jpg