using System; using System.Collections.Generic; using System.IO; using MikuMikuDance.Model.Ver1; namespace MikuMikuDance.Model { /// /// MikuMikuDance(MMD)モデルの入出力の管理を行うFactory Class /// public static class ModelManager { /// /// ライブラリユーザー拡張用 /// /// ここにMMDモデルを継承したクラスと使用するバージョン番号を登録すると、既存クラスの代わりに、登録したクラスが使用される public static readonly Dictionary OriginalObjects = new Dictionary(); /// /// ファイルからMMDモデルを読み込む /// /// MMDモデルファイル /// 変換先座標系 /// スケーリング値 /// MMDモデルオブジェクト /// MMDの座標系は右手座標系です public static MMDModel Read(string filename, CoordinateType coordinate, float scale=1f) { //フルパス取得 filename = Path.GetFullPath(filename); //ファイルチェック if (!File.Exists(filename)) throw new FileNotFoundException("MMDモデルファイル:" + filename + "が見つかりません"); //戻り値用変数 MMDModel result = null; //ファイルリーダー using (FileStream fs = new FileStream(filename, FileMode.Open)) { BinaryReader reader = new BinaryReader(fs); //マジック文字列 string magic = MMDModel1.encoder.GetString(reader.ReadBytes(3)); if (magic != "Pmd") throw new FileLoadException("MMDモデルファイルではありません"); //バージョン float version = BitConverter.ToSingle(reader.ReadBytes(4), 0); if (OriginalObjects.ContainsKey(version) && OriginalObjects[version].BaseType == typeof(MMDModel)) {//このバージョンで使用し、利用可能型 result = (MMDModel)OriginalObjects[version].InvokeMember(null, System.Reflection.BindingFlags.CreateInstance, null, null, null); } else { if (version == 1.0) result = new MMDModel1(); else throw new FileLoadException("version=" + version.ToString() + "モデルは対応していません"); } result.Read(reader, coordinate, scale); if (fs.Length != fs.Position) Console.WriteLine("警告:ファイル末尾以降に不明データ?"); fs.Close(); } return result; } /// /// ファイルにMMDモデルを書きだす /// /// 書きだすファイル名 /// モデルオブジェクト /// スケーリング値 public static void Write(string filename, MMDModel model, float scale = 1f) { //フルパス取得 filename = Path.GetFullPath(filename); //ファイルリーダー using (FileStream fs = new FileStream(filename, FileMode.Create)) { BinaryWriter writer = new BinaryWriter(fs); //マジック文字列 writer.Write(MMDModel1.encoder.GetBytes("Pmd")); //バージョン writer.Write(model.Version); //中身の書きだし try { model.Write(writer, scale); } catch (NullReferenceException e) { throw new ArgumentNullException("modelの中の変数がnull", e); } fs.Close(); } } /// /// ファイルからMMDモデルを読み込む /// /// MMDモデルファイル /// MMDモデルオブジェクト /// MMDの座標系は右手座標系です public static MMDModel Read(string filename) { return Read(filename, CoordinateType.LeftHandedCoordinate); } } }