次: その2
#はじめに
##やりたいこと
伺かみたいなのをMMDモデルで。何か起動させたり実行させたりしたい。
「MMDDM」は表示させるのみ、既に公開されている「MMD版伺か」は開発中途であり、DXライブラリを使用しているため、PMXモデルの表示に難がある。
→ PMDを扱えるライブラリは「MMDX」などがあるが、PMXに対応しているものはほとんどない。(MMFlexは凍結中?)
→ なら自分でつくればいいじゃない
##とりあえずやること
- モデルの読み込み ←イマココ
- モデルの表示
- スキニング・IK
- PMX対応
##開発環境など
C# + SlimDX(DirectX11) (+ WPF)
PMDモデルはえと式チルノを使用
#PMD読み込みクラスの作成
DirectXでモデルを表示するために、まずはモデルファイルの読み込みを行います。
MMDのモデルデータには、PMDとPMXの2つがありますが、しばらくはPMDを使って開発していきます。
PMXは、PMDモデルの表示がある程度でき次第、とりかかる予定です。
##読み込むにあたっての注意点・つまづいた点
PMDの中身はこちらで公開されているので、これを参照しながら読み込んでいきます。
ソースはGitHubで公開しています。後日、VMDやPMXの読み込みも追加する予定です。
PMDファイルはバイナリデータ(not テキストデータ)なので、FileStreamでファイルを開き、BinaryReaderで読み込んでいきます。このとき、エンコーディングにはShift-JISを指定します。
###ヘッダ部分の読み込み
ヘッダはPMDファイルであることを表すマジック(3byte)、バージョン(4byte)、モデル名(20byte)、コメント(256byte)で構成されています。
マジック・モデル名・コメントは文字列、バージョンは実数なので、ReadBytes(int 文字数)とReadSingle()を使用します。
エンコーディングがShift-JISなため、ReadCharsを使用すると、ヘッダの次の頂点の領域まで余分に読んでしまうので注意が必要です。
また、PMDファイルの文字列は、文字の終わりに0x00, パディングとして0xFDで埋められているので、文字の終端までを返す関数を用意します。
using System.IO;
using System.Text;
class PmdLoad {
public PmdHeader Header;
public PmdLoad(string modelfilename) {
using(var fs = new FileStream(Path, FileMode.Open))
using(var br = new BinaryReader(fs, Encoding.GetEncoding("shift-jis"))) {
Header = new PmdHeader(br);
}
}
public static string Sjis(this BinaryReader br, int count) {
var tmp = Encoding.GetEncoding("shift-jis").GetString(br.ReadBytes(count));
if(tmp.IndexOf('\0') > 0) return tmp.Substring(0, tmp.IndexOf('\0'));
else return tmp;
}
}
class PmdHeader {
public string ModelName;
public string Comment;
public PmdHeader(BinaryReader br) {
br.Sjis(3); //マジック(読み飛ばし)
br.ReadSingle(); //バージョン(読み飛ばし)
ModelName = br.Sjis(20);
Comment = br.Sjis(256);
}
}
(例外処理等はしてないです)
こんな調子でこの後の頂点リストやインデックスリストなどを読み込んでいきます。
PMDファイルにはテクスチャファイル名の指定の方法にバリエーションがあったり、物理演算に必要な剛体やジョイント関係のデータが格納されている/いないなどあるようですが、一番最新のものを基準に読み込みをしています。
最後にPMDEditorと読み込んだものを確かめて、問題がなければ終了です。
##おわりに
PMDの読み込みができたので、次回からはSlimDXを使用して、モデルの表示の準備をする予定です。